Compare commits

...

261 Commits

Author SHA1 Message Date
Charles Hacskaylo
42ddb38629 [Front-end] Cleanups to imagery in frame
Fixes #1704
Imagery now lays out better when very small
in a Layout; refactored .left and .right classes;
2017-09-14 10:37:41 -07:00
Charles Hacskaylo
fe60d7abbc [Front-end] Fix CSS targeting
Fixes #1704
Pause/play and New Tab buttons now
display properly;
2017-09-14 10:25:34 -07:00
Pete Richards
54b975f242 Merge pull request #1699 from nasa/imagery-issue-1676
Imagery issue #1676
2017-09-12 11:28:40 -07:00
Deep Tailor
7f75e089e8 remove workaround for Imagery Thumbnail resizing from MCTSplitPane and add box sizing to thumbs wrapper to fix phantom resizing 2017-09-11 16:35:14 -07:00
Charles Hacskaylo
8e8c66280f Fix for Issue #1676
Add history imagery under large imagery view.
Allow users to click on history imagery thumbs to set main image and pause the imagery view.
Allow users to unpause and continue imagery stream.
Users can adjust the height of the imagery panes, and the user selected height is persisted.
2017-09-11 12:51:04 -07:00
Pete Richards
d3d874e209 Merge pull request #1702 from nasa/glyphs-update-import-export
[Glyphs] Add import and export icons
2017-09-11 12:01:04 -07:00
Charles Hacskaylo
ce561e1598 [Glyphs] Add import and export icons
For #1695
2017-09-11 11:41:19 -07:00
Victor Woeltjen
7290601a37 Merge pull request #1698 from nasa/plot-metadata-1684
[Telemetry] Provide legacy domains/ranges
2017-09-06 08:31:47 -07:00
Victor Woeltjen
ea5a85ffd1 [Telemetry] Verify legacy domains/ranges conversion
Verify that domains and ranges are populated in legacy telemetry
metadata when converted from the current telemetry metadata API.
2017-08-30 09:44:38 -07:00
Victor Woeltjen
eb196ea521 [Telemetry] Convert to legacy domains/ranges
When requesting metadata via the legacy telemetry capability,
add fields for ranges/domains to avoid breaking legacy views.
Fixes #1684
2017-08-30 09:31:02 -07:00
Victor Woeltjen
b6a8078634 Merge pull request #1692 from nasa/timeline-issue-1686
update mct-split-pane to use userPreferenceWidth only when alias is p…
2017-08-29 11:56:27 -07:00
Deep Tailor
e53b34ed60 move newPosition check from mctSplitPane to splitter 2017-08-29 11:50:20 -07:00
Victor Woeltjen
13ffa3e3c4 Merge pull request #1693 from nasa/fix-selector-1685
Fix Selector Pool Control
2017-08-29 11:36:47 -07:00
Deep Tailor
0e3b629d90 update changes requested by victor and update corresponding tests 2017-08-29 11:27:01 -07:00
Charles Hacskaylo
23216e5aee [Frontend] Restored commented SASS
Fixes #1685
2017-08-29 11:24:40 -07:00
Victor Woeltjen
5b366e91c1 Merge pull request #1665 from nasa/import-export
[Import/Export] [WIP] Allows for import and export of domain objects

Fixes #593
2017-08-29 11:19:29 -07:00
Deep Tailor
aa336dfd57 fix gulp checkstyle errors 2017-08-29 10:45:41 -07:00
Deep Tailor
556296096d fix tests to correspond with changes made to MCTSplitPane 2017-08-29 10:34:44 -07:00
Deep Tailor
e4aaa860a3 update mct-split-pane to use userPreferenceWidth only when alias is provided, otherwise set position as usual (fix for timeline sync issue) 2017-08-29 10:15:29 -07:00
Victor Woeltjen
2079a74ab2 Merge pull request #1691 from nasa/apimd-typo
[Documentation] Fix typo
2017-08-29 09:49:49 -07:00
Victor Woeltjen
4b86439b8a [Documentation] Fix typo
Omitting checklist; changes to documentation only
2017-08-29 09:43:08 -07:00
Victor Woeltjen
a4d8e8ff90 Merge pull request #1683 from nasa/limits-1677
Review limit and status CSS classes
2017-08-28 12:35:24 -07:00
Preston Crowe
3674808a13 [Import/Export] Adds Import and Export functionality
Added context actions for importing and exporting JSON representations of domain objects. Added FileInputService for triggering file picker and retrieving uploaded data. Also added a File Input form control for integration with MCTForms.
2017-08-25 19:28:29 -04:00
Charles Hacskaylo
10c0c29f64 [Frontend] Doc style tweak
Fixes #1677
2017-08-23 16:16:53 -07:00
Charles Hacskaylo
fa1a942184 [Frontend] Content tweak
Fixes #1677
2017-08-23 16:12:14 -07:00
Pete Richards
e205bf1fa4 Merge pull request #1666 from nasa/layout-issue-1658
Added selection capability for the panels in layout. Also, added a to…
2017-08-22 17:31:52 -07:00
Pegah Sarram
cecd708dd1 Layout selection and show/hide frame
Added ability to show/hide object frames via a toggle button in the
edit toolbar. All objects have frames by default except for ‘hyperlinks’.
Also, implemented object selection in the layout and added tests for new features.

Fixes #1658.
2017-08-22 16:45:34 -07:00
Charles Hacskaylo
aa36417590 [Frontend] Limits and Status classes
Fixes #1677
Style Guide content updates;
Reviewed against current master for regression;
TO-DO: review against new plot functionality;
2017-08-22 10:27:37 -07:00
Charles Hacskaylo
e6c78f6d8b [Frontend] Style Guide updates for status classes
Fixes #1677
WIP, needs regression unit testing
2017-08-22 10:09:01 -07:00
Charles Hacskaylo
747afa6200 [Frontend] WIP
Fixes #1677
Refactor and re-organize alert and status colors;
Rename _limits.scss to _status.scss;
Style Guide additions in progress;
VERY WIP, NEEDS UNIT TESTING FOR REGRESSION.
2017-08-17 16:32:25 -07:00
Pegah Sarram
019cdde1c6 Merge pull request #1655 from nasa/subscribe-once
[Telemetry API] many subscribes -> one provider subscribe
2017-08-17 16:24:57 -07:00
Pete Richards
c7e26a231a [Style] Remove unnecessary comments 2017-08-17 16:13:49 -07:00
Pete Richards
f3b519d47b Merge pull request #1672 from nasa/paneController-Issue#1670
Fix for Pane controller issue#1670
2017-08-17 16:10:20 -07:00
Deep Tailor
c472ab044b Add functionality to allow users to add hideParameters to the url, which will hide tree and/or the inspector
New Tab automatically appends hideTree and hideInspector params to hide those panes by default
Add appropriate tests for new functionality and fix broken tests
2017-08-17 15:25:01 -07:00
Charles Hacskaylo
008f1387ed Merge remote-tracking branch 'origin/master' into limits-1677 2017-08-17 14:56:11 -07:00
Charles Hacskaylo
6ed76708ec [Frontend] WIP adding status classes
Fixes #1677
2017-08-17 11:30:00 -07:00
Charles Hacskaylo
c2ff81bad1 [Frontend] Add .w-mct-example to mct-example.html
Fixes #1677
2017-08-17 11:28:14 -07:00
Charles Hacskaylo
a6c3d98ddd [Frontend] Update Style Guide to add Status Indication
Fixes #1677
2017-08-17 11:27:35 -07:00
Charles Hacskaylo
603e990755 [Frontend] Refactoring of limits CSS
Fixes #1677
Removed `<tr>` support; modded existing styles to allow
color-only application for red and yellow limits; added
`*-icon` classes for red and yellow limits;
2017-08-17 09:08:12 -07:00
Pete Richards
586901aee7 Merge pull request #1663 from dtailor90/master
persist user preference width for MCTSplitPanes issue #1646
2017-08-16 15:31:26 -07:00
Deep Tailor
449923feae Persist User preference widths for MCTSplitPane
Fix to Issue #1646
Persist MCTSplitPane widths to local storage, thus when user reloads, the Panes maintain dimensions
Use persisted widths if available otherwise use default
Add tests for localStorage and fix failing tests
2017-08-16 15:04:33 -07:00
Deep Tailor
ae461f71b4 Merge pull request #1675 from nasa/limit-example-telemetry-response-sizes
[Example] Limit telemetry responses to 5000 records
2017-08-16 10:34:24 -07:00
Pete Richards
5243b3748d [Example] Limit telemetry responses to 5000 records
Update example telemetry providers to limit the number of
datums generated so that queries for long time ranges will
not cause undesired behavior in demos.
2017-08-15 14:34:36 -07:00
Pete Richards
82a661b884 Merge pull request #1674 from nasa/hyperlink-styling
Hyperlink styling
2017-08-14 13:04:26 -07:00
Charles Hacskaylo
f5a92f66db [Front-end] Hyperlink styling
Change icon for Hyperlink
2017-08-14 12:40:00 -07:00
Charles Hacskaylo
0417b7e32d [Front-end] Hyperlink styling 2017-08-14 12:38:01 -07:00
Charles Hacskaylo
7c9a6bd817 [Front-end] Integrate Hyperlink related changes from #1685 work
Fixes #1685
(cherry picked from commit 4dff369)
2017-08-14 12:18:19 -07:00
Pete Richards
a58c484d71 Merge pull request #1673 from nasa/glyph-update-frame
[Frontend] Updated glyphs
2017-08-14 09:38:07 -07:00
Charles Hacskaylo
43b92647fb [Frontend] Updated glyphs
Updated art for glyphs for
icon-frame-show and -hide;
2017-08-11 14:35:21 -07:00
Pete Richards
e8eb34f5c3 Merge pull request #1660 from sahajp23/master
Updated Hyperlink Domain Object with suggested changes
2017-08-11 14:10:25 -07:00
sahajp23
fa57688709 Bug fix for hyperlink in Display Layout 2017-08-11 11:59:27 -07:00
Pete Richards
5ac377ec6a Merge pull request #1667 from nasa/glyphs-update
Glyphs update 08-08-2017
2017-08-08 12:54:26 -07:00
Charles Hacskaylo
c523480b48 [Glyphs] Updated icomoon 16px project file 2017-08-08 11:47:29 -07:00
Charles Hacskaylo
4dc09975d0 [Style Guide] Glyphs additions and subtractions
Removed unused 12px glyphs;
Added 16px crosshair;
Fixed erroneously removed overlay plot glyph;
Updated style guide content
2017-08-08 11:41:55 -07:00
Charles Hacskaylo
29a472ae5d [Style Guide] Tweak Style Guide CSS 2017-08-08 10:38:41 -07:00
sahajp23
3e2fd8967a The second update of the Hyperlink Domain Object with fixed changes 2017-08-03 14:34:43 -07:00
Pete Richards
9e429802c2 Merge pull request #1657 from nasa/handle-invalid-time-url
[Time] Handle missing time system gracefully
2017-08-02 15:51:04 -07:00
Aaron Doubek-Kraft
6cfee100d7 Merge branch 'master' into handle-invalid-time-url 2017-08-02 15:44:18 -07:00
Pete Richards
eeb214204d Merge pull request #1662 from nasa/revert-1659-master
Revert "persist user preference width for MCTSplitPanes issue #1646"
2017-08-02 10:53:07 -07:00
Deep Tailor
b41ceab51e Revert "persist user preference width for MCTSplitPanes issue #1646" 2017-08-02 10:48:57 -07:00
Deep Tailor
10b0f43fc1 Merge pull request #1659 from dtailor90/master
persist user preference width for MCTSplitPanes issue #1646, updated MCTSplitPane to handle logic regarding localStorage
2017-08-02 10:48:51 -07:00
Deep Tailor
593c1adf56 updated mctSplitPane to handle all logic regarding persisting userPreferenceWidth to local storage 2017-08-02 10:46:14 -07:00
Charles Hacskaylo
2d1ee80322 [Glyphs] Update glyphs
Add grid snap and layout show/hide frame
glyphs
2017-08-01 15:50:30 -07:00
Charles Hacskaylo
7555eab1e3 [Glyphs] Bring in updated version of glyphs
Add glyphs from summary widgets
2017-08-01 15:43:32 -07:00
Charles Hacskaylo
4923bcbd85 [Glyphs] Bring in updated version of glyphs
Add glyphs from summary widgets
2017-08-01 15:40:43 -07:00
Deep Tailor
5a7fdf82ac persist user preference width for MCTSplitPanes 2017-08-01 12:00:21 -07:00
sahajp23
a5f6940d67 Updated version of hyperlink with suggested changes made
modified:   src/defaultRegistry.js
2017-08-01 11:51:42 -07:00
Pete Richards
4571205871 [Time] Handle missing time system gracefully
When loading the application and no time system is set,
the url handler should not cause multiple errors to be
logged.

This adds a test for the case but does not specify the
expected behavior in detail, other than "it should not
crash."

Fixes bugs as reported here.
2017-07-27 15:38:42 -07:00
Pete Richards
34c3763421 Merge pull request #1635 from nasa/historical-imagery
[Historical imagery] [WIP]: Add historical view for image telemetry
2017-07-26 11:36:21 -07:00
Pete Richards
e45a686c5a [Telemetry] Combine subscriptions for points
The telemetry API detects when a subscription has already been made for a
given domain object and does not subscribe for that object a second time.
Removes a concern from those developing telemetry providers.

Also ensures that telemetry providers ALWAYS get request options, even if
no request options were provided.

Adds basic tests for the Telemetry API to validate this behavior.

Fixes https://github.com/nasa/openmct/issues/1594
2017-07-21 16:38:47 -07:00
Pete Richards
1c33157fb8 [Telem] Handle no range values
Update the telemetry adapter to gracefully handle cases where
a range value is not found via hints.  This allows telemetry objects
that don't have ranges to still work with some old style displays
2017-07-21 16:29:54 -07:00
Preston Crowe
ed6ae23dc0 [Historical Imagery] JSDoc, code review style changes
Added $element dependency and JSDoc for private methods. Autoscroll is now enabled by default when there is an active clock. Inline comments removed.
2017-07-14 13:05:59 -07:00
Pete Richards
23839b05b0 Merge pull request #1643 from nasa/open1641
[Open 1641] Change warnings to info messages
2017-07-13 17:23:10 -07:00
Pete Richards
6aed3bb0b5 Merge pull request #1638 from nasa/only-time-change-when-changed-1636
[Time API] Only change time when changed
2017-07-13 17:11:59 -07:00
Pete Richards
1ae62cde05 [Browse] Don't klobber params when preventing default
When browse controller is hijacking a browser navigation event,
it calls preventDefault on the route change.  This has the effect
of preventing all changes in the location (including search changes).

This change checks if other changes were made in the route change and
re-applies them after the navigation has completed.

Fixes a bug where navigating via a link that contained additional
search paramterers would have the effect of navigating but not
keeping the parameters in tact.

Discovered in the course of fixing #1636
2017-07-13 16:48:38 -07:00
Pete Richards
4e7e5bb783 [Time] Conductor changes based on click not scope
Update time conductor so that it triggers changes when the user
selects them instead of when the scope is updated.  Prevents spurious
changes from being triggered by the conductor when it updates
in response to a time API change.

Fixes #1636.
2017-07-13 16:48:38 -07:00
Luis-Johannes Schubert
efc46613bb Updated TelemetryCapability.js
removed outdated comment.
2017-07-13 16:47:24 -07:00
Preston Crowe
218ef16160 [Imagery] Implemented historical view for imagery
Implemented auto-scrolling historical imagery view in ImageryController. Imagery domain objects now request historical data on each manual bounds change. Added new specs for ensuring that historical data is requested on bounds change and duplicate bounds / datum are ignored.
2017-07-12 12:13:57 -07:00
Luis Schubert
fb0a577d16 [Open1641] Updated the spec files to check for info messages instead of warning messages 2017-07-10 09:46:51 -07:00
Luis Schubert
19b5e7c781 [Open 1641] Change warnings to info messages 2017-07-06 15:55:29 -07:00
Luis-Johannes Schubert
0794c0edf7 Merge pull request #1640 from nasa/fix-error-on-table-destroy
[Resize] don't trigger callback after being destroyed
2017-07-05 17:24:16 -07:00
Pete Richards
89515bb896 verify that eval isn't called after destroy 2017-07-05 16:48:09 -07:00
Pete Richards
318aecb7bc Merge pull request #1634 from nasa/open1405
[Fixed Position] Add numerical inputs for size and position of elements
2017-07-05 11:45:36 -07:00
Aaron Doubek-Kraft
a4b857a034 [Fixed Position] Change default behavior for old elements
For elements created before this change where useGrid is not defined,
default it to true to ensure consistent display size

Inline constant definitions in unit tests if they are only used once
2017-07-05 10:58:13 -07:00
Pete Richards
d82230dea4 [Resize] don't trigger callback when destroyed
Prevent MCTResize from triggering a callback after it is destroyed.

Fixes https://github.com/nasa/openmct/issues/1509
2017-07-04 17:03:25 -07:00
Pete Richards
cb242d8efb [TimeAPI] check for change before triggering
Update the TimeSettingsURLHandler to check for changes to the search
parameters and only trigger a bounds change when there is a change.

Added integration tests between Time API and settings url handler.

Prevents extraneous bounds events.

Fixes https://github.com/nasa/openmct/issues/1636
2017-07-04 15:09:56 -07:00
Aaron Doubek-Kraft
aa8f780e4e [Fixed Position] Add unit tests 2017-06-29 15:22:39 -07:00
Aaron Doubek-Kraft
3ed0880c6e [Fixed Position] Add unit tests for new code
Refactored ElementProxy and UnitAccessorMutator slightly to improve encasulation. Added unit tests for UnitAccessorMutator
2017-06-29 13:14:38 -07:00
Aaron Doubek-Kraft
40c68e6399 [Fixed Position] Change UI pixel/grid toggle to checkbox
Change the input for grid units/pixels to a simple checkbox toggle from a
dropdown menu.

Add a new specialized AccessorMutator class to support this operation.
2017-06-28 15:19:18 -07:00
Aaron Doubek-Kraft
65500736da [Fixed Postion] Update unit tests for new code 2017-06-28 13:38:35 -07:00
Aaron Doubek-Kraft
b9ab97eb7f [Fixed Position] Add ability to work in pixel space
Fix code style issues per Victor's review

Add toggle to work in pixel space or grid space, per the issue description.
Each element stores a boolean property that determines whether or not it
snaps to grid space or pixel space. Coordinates are converted between spaces
on toggle, preserving the size of the element in pixels.

To complete: change UI element for toggle to a checkbox.
2017-06-28 12:37:14 -07:00
Victor Woeltjen
34ef98e0cd Merge pull request #1595 from dhrubomoy/timezone_dropdown_feature
[CLOCK] Allow clock to set timezone with autocomplete dropdown option.
2017-06-26 16:51:30 -05:00
Aaron Doubek-Kraft
825f50262c [Fixed position] Incorporate numberfield control
Fix style and merge issues
2017-06-26 11:15:09 -07:00
Aaron Doubek-Kraft
a6079936e8 [Fixed position] Incorporate numberfield control 2017-06-26 11:07:20 -07:00
Aaron Doubek-Kraft
542b7a6f20 [Fixed Position] Incorporate numberfield control
Change inputs from textfield to new numberfield input, remove internal type checking in favor of input validation
2017-06-26 10:57:47 -07:00
Aaron Doubek-Kraft
2a8c3977a4 [Fixed Position] Incorporate new numberfield inputs
Changed inputs from textfields to numberfields, and removed internal
type checking for these inputs
2017-06-26 10:52:04 -07:00
Doubek-Kraft
515ea7caf8 [Layout] Code Style Issues 2017-06-26 09:36:31 -07:00
Doubek-Kraft
65993bd77f [Layout] Code style
Fix code style issues
2017-06-26 09:36:31 -07:00
Doubek-Kraft
54e07ccfdd [Layout] Line endpoint coordinate editing
Added appropriate line endpoint coordinate editing input fields
2017-06-26 09:36:31 -07:00
Doubek-Kraft
2e6fcec1c3 [Layout] Consistent input behavior
Inputs now handle invalid input consistently for all fields
2017-06-26 09:36:31 -07:00
Doubek-Kraft
f992fcebe1 [Layout] Consistent input behavior
Inputs now consistently default to 0 when left empty
2017-06-26 09:36:31 -07:00
Doubek-Kraft
280c838735 [Layout] Add numerical inputs for fixed-position layout
Added individual property inputs to the toolbar for height, width, x,
 y, and line endpoint coordinates in fixed/bundle.js.

Added "edit<Property>" AccessorMutators for height and width to each
of the element proxies, so these properties can be exposed only for
elements where it makes sense (e.g. boxes, but not lines, since lines
are better controlled by endpoint coordinates).

Added a method "checkNumeric" to ElementProxy.js , to be used
to restrict inputs to integral values for position and size
 textfield inputs.

Current issues: endpoint coordinate inputs have undexpected behvaior,
handles disappear after using the input fields to modify element
properties.
2017-06-26 09:36:31 -07:00
Pete Richards
445dfb3d91 Merge pull request #1633 from nasa/revert-1632-historical-imagery
Revert "Historical imagery "
2017-06-25 21:51:31 -07:00
Preston Crowe
bc616ecdee Revert "Historical imagery " 2017-06-25 20:46:09 -07:00
Preston Crowe
895c9b12e6 Merge pull request #1632 from nasa/historical-imagery
Historical imagery
2017-06-25 20:45:19 -07:00
Preston Crowe
95e68fce57 Integrated historic and realtime telemetry in imagery timeline view, added sass constast for timeline hover color 2017-06-25 13:02:04 -07:00
Preston Crowe
9f4f771774 Updated stylesheet 2017-06-25 13:02:04 -07:00
Preston Crowe
05290593e9 Added imagery timeline view for telemetry sources and placeholder template for displaying historical imagery 2017-06-25 13:02:04 -07:00
Pete Richards
2aa2d9d4bb Merge pull request #1629 from nasa/number-input
Review and integrate new Number input for mct-control
2017-06-25 12:53:11 -07:00
Dhrubomoy Das Gupta
7b690d0785 Revert "[Autocomplete] Show warning icon if invalid option was typed"
This reverts commit 307320b3ff.
2017-06-25 14:58:28 -04:00
Doubek-Kraft
39fe2fd7b6 [Layout] Code Style Issues 2017-06-23 16:04:34 -07:00
Doubek-Kraft
b661b4737e [Layout] Code style
Fix code style issues
2017-06-23 14:47:01 -07:00
Charles Hacskaylo
9ca8975baf [Documentation] Add number input
Fixes #1628
numberfield added to .md files;
2017-06-23 14:32:21 -07:00
Doubek-Kraft
5f7eeeae30 [Layout] Line endpoint coordinate editing
Added appropriate line endpoint coordinate editing input fields
2017-06-23 13:48:33 -07:00
Doubek-Kraft
537656303a [Layout] Consistent input behavior
Inputs now handle invalid input consistently for all fields
2017-06-23 11:42:52 -07:00
Charles Hacskaylo
e7ba13f844 [Frontend] Add number input
Fixes #1628
Add template and bundle info for numberfield;
Styling in general and toolbar contexts;
2017-06-23 11:07:24 -07:00
Doubek-Kraft
64bf63c18a [Layout] Consistent input behavior
Inputs now consistently default to 0 when left empty
2017-06-23 10:57:50 -07:00
Doubek-Kraft
ac3f638b35 [Layout] Add numerical inputs for fixed-position layout
Added individual property inputs to the toolbar for height, width, x,
 y, and line endpoint coordinates in fixed/bundle.js.

Added "edit<Property>" AccessorMutators for height and width to each
of the element proxies, so these properties can be exposed only for
elements where it makes sense (e.g. boxes, but not lines, since lines
are better controlled by endpoint coordinates).

Added a method "checkNumeric" to ElementProxy.js , to be used
to restrict inputs to integral values for position and size
 textfield inputs.

Current issues: endpoint coordinate inputs have undexpected behvaior,
handles disappear after using the input fields to modify element
properties.
2017-06-23 09:28:49 -07:00
Victor Woeltjen
a3520ba51e Merge pull request #1625 from nasa/example-historical-imagery
Example historical imagery
2017-06-22 16:18:49 -05:00
Pete Richards
8e0b7fce7f Merge pull request #1627 from nasa/time-system-key
[Time] Tolerate unset Time API properties from URL handler
2017-06-22 13:09:31 -07:00
Victor Woeltjen
52f5bea215 [Time] Add clarifying comment to NULL_PARAMETERS 2017-06-22 12:58:14 -07:00
Victor Woeltjen
26b4e5498f [Time] Tolerate unset Time API properties
...from the URL handler. Fixes nasa/openmct-tutorial#14
2017-06-22 12:51:44 -07:00
Victor Woeltjen
ce733628b2 [Time] Add test cases for URL handler
To reproduce root cause of nasa/openmct-tutorial#14
2017-06-22 12:40:02 -07:00
Dhrubomoy Das Gupta
307320b3ff [Autocomplete] Show warning icon if invalid option was typed 2017-06-21 22:35:32 -04:00
Dhrubomoy Das Gupta
504b2e1ecf [Autocomplete] Update test 2017-06-21 18:14:14 -04:00
Pete Richards
73e452edc0 [Imagery] Update spec 2017-06-21 14:56:51 -07:00
Pete Richards
bbeb97e93c [Imagery] Use LAD query 2017-06-21 14:21:51 -07:00
Pete Richards
e6d65f3549 [Example] Add historic, lad imagery providers 2017-06-21 14:17:18 -07:00
Pete Richards
1ab4cf68d7 [example] 5 seconds per image 2017-06-21 13:56:18 -07:00
dhrubomoy
f20c8b7d99 Fix code style and add missing semicolons 2017-06-21 15:29:28 -04:00
dhrubomoy
17a067752f [Forms] Remove redundant mctClickElsewhere 2017-06-21 14:31:55 -04:00
Pete Richards
7fcaf6510e Merge pull request #1614 from nasa/open1569
Fixed tabbing in overlay forms
2017-06-21 11:24:23 -07:00
Victor Woeltjen
0713941812 [Time] Encode time settings in URL (#1620)
* [Time Conductor] Skeleton class for URL handling

#1550

* [Time Conductor] Scaffold in param handling

* [Time Conductor] Finish sketching in URL handler

* [Time Conductor] Usage correct constants for bounds

* [Time Conductor] Use start/end for bounds/deltas

* [Time] Move URL handler

Per discussion, https://github.com/nasa/openmct/issues/1550#issuecomment-308849449

* [Time] Rename URL handler

* [Time] Rename URL handler script

* [Time] Use Time API from URL handler

* [Time] Utilize Time API

* [Time] Listen for changes, synchronize URL

* [Time] Move URL handler into adapter

...as it uses Angular constructs.

* [Time] Wire URL handler into adapter bundle

* [Time] Pass correct constructor arguments to URL handler

* [Time] Begin debugging URL handling

* [Time] Clarify and correct logic for bounds/deltas in URL

* [Time] Define timeSystem

* [Time] Pass start/end into time API as numbers

...instead of strings.

* [Time] Avoid creating redundant objects

* [Time] Restructure fixed vs clock logic

* [Time] Stop clock correctly for fixed mode

* [Time] Fix hasBounds/hasDeltas logic

...given that both inputs will be strings when read from search params,
_.isFinite was doomed to return false.

* [Time] Check for complete information

...before updating Time API to reflect search state. Additionally,
flatten logic to ease readability.

* [Time] Begin testing TimeSettingsURLHandler

* [Time] Test fixed mode query string updates

* [Time] Test realtime mode query string updates

* [Time] Test update of time API from query params

* [Time] Add missing semicolons

Satisfies JSHint; fixes #1550
2017-06-21 11:23:18 -07:00
Pete Richards
1d7d56d5e7 Merge pull request #1613 from nasa/open1592
[Frontend] Fixed markup to allow scroll of results
2017-06-21 11:10:14 -07:00
Pete Richards
ba9941891d Merge pull request #1612 from nasa/no-keyframe-anims
Review and merge no-keyframe-anims branch
2017-06-21 11:08:23 -07:00
Pete Richards
d3b313d8aa Merge pull request #1619 from nasa/enable-tc
[Time Conductor] Enable time conductor in dev environment
2017-06-19 18:37:43 -07:00
Luis-Johannes Schubert
e2f0f61862 Implement new folder List view (#1610)
* refactored code for listView

* minimum viable folder list functionality

* moved listview directory inside of platform/features

* [Folder ListView] First Code Review Fixes

Changes made:
Updated listview icon as the hamburger menu.
Injecting listview template as textfile instead of using the template's url.
Added callback to $scope to listen for $destroy to release resources for the mutation listener and the gesture recognizer.
Refactored ListViewController formatting function to use map instead of foreach.
Added listview plugin to the default registry.
Updated table styling.

* working progress commit. ListViewControllerSpec is implemented and all tests are passing. MCTGestureSpec is not fully implemented. Testing the gestureService release is in progress.

* All tests in MCTGestureSpec and ListViewControllerSpec are passing.

* ListViewControllerSpec and MCTGesture Tests all passing.

* refactored variable names in ListviewController to make more sense.

* [Frontend] Styling of Luis's list view WIP

Fixes #1615
This will have conflicts with Luis's work,
be careful!

* [Folder ListView] Second Code Review Fixes

Changes made:
updated listview to utilize open-mct sorting style.
added license comments to all files.
modified mctgesture interface to use $scope.eval().

* [Frontend] Styling of Luis's list view WIP

Fixes #1615
New list-view glyph added

* [Frontend] Styling of Luis's list view WIP

Fixes #1615
Changed name of "Items" view to "Grid";

* [Frontend] Styling of Luis's list view WIP

Fixes #1615
Updated icomoon project file with new list-view
glyph e1042;

* [Folder ListView] Second Code Review Fixes

Changes made:
updated listview to utilize open-mct sorting style.
added license comments to all files.
modified mctgesture interface to use $scope.eval().

* [Frontend] Styling of Luis's list view WIP

Fixes #1615
Refined cursor CSS;

* [Frontend] Styling of Luis's list view WIP

Fixes #1615
Added logic to refine how sorting occurs:
now, clicking a table header that wasn't
the orderByField always sorts by its default;
2017-06-19 18:35:18 -07:00
Pete Richards
ecdcebce0c Merge pull request #1606 from nasa/headers-1541
[Build] Remove/reorganize version headers
2017-06-19 18:22:17 -07:00
Pete Richards
5fbf71264e Merge pull request #1563 from nasa/open-623
[Timers] Add stop button
2017-06-19 18:20:25 -07:00
Victor Woeltjen
8519e7660f [Time Conductor] Enable time conductor by default
Supports #1550.
2017-06-15 16:29:52 -07:00
Victor Woeltjen
e75d1f62ec Merge pull request #1600 from nasa/imagery-updates
[Imagery] Update metadata for images
2017-06-13 16:30:33 -05:00
Victor Woeltjen
1c9a9baf77 [Imagery] Check for pending updates when unpausing
https://github.com/nasa/openmct/pull/1600#discussion_r119931468
2017-06-13 14:25:35 -07:00
Charles Hacskaylo
44246e6973 [Frontend] Modified tabindex of search input
Fixes #1569
2017-06-13 14:14:39 -07:00
Charles Hacskaylo
61f59a94e4 [Frontend] Fixed markup to allow scroll of results
Fixes #1592
2017-06-13 09:24:42 -07:00
Charles Hacskaylo
a8a689f69a [Frontend] WIP remove keyframe anims
Fixes #1603
Remove keyframe anims from transition to edit mode
and border-color anim in _messages.scss;
2017-06-09 11:40:58 -07:00
Dhrubomoy Das Gupta
e3bd22de8c [Autocomplete] Minor refactoring 2017-06-07 23:01:14 -04:00
Charles Hacskaylo
c7787aa1f0 [Frontend] WIP remove keyframe anims
Fixes #1603
Remove keyframe anims from transition to edit mode
2017-06-06 16:18:22 -07:00
Dhrubomoy Das Gupta
3870266131 [Autocomplete] Clicking the arrow will display the entire list of timezones
This change is based on the  following code review:
- Display the entire list of timezones, regardless of what's currently entered.
- As soon as the user typed (or deleted chars in the input) then that filtration would take over the list display
2017-06-06 18:55:16 -04:00
Dhrubomoy Das Gupta
98cc19c637 [Autocomplete] Check if indexed filteredOptions is defined 2017-06-04 17:49:31 -04:00
Victor Woeltjen
c1128c3156 [Build] Move version comment header into template file
Fixes #1541
2017-06-02 12:40:23 -07:00
Victor Woeltjen
485944a782 [Build] Normalize whitespace in header template 2017-06-02 12:24:25 -07:00
Victor Woeltjen
beb24adf7a [Build] Simplify header template 2017-06-02 12:23:57 -07:00
Victor Woeltjen
6de5f73d78 [Build] Remove obsolete version header 2017-06-02 12:19:37 -07:00
Victor Woeltjen
35b51d151d Merge pull request #1598 from slinto/mct1541
[Build] Include version information in openmct.js
2017-06-02 14:09:45 -05:00
Victor Woeltjen
b2333d83d2 [Imagery] Update policy spec
Fixes #1591
2017-06-01 18:46:22 -07:00
Victor Woeltjen
7513f24ff3 [Imagery] Update value testing in spec 2017-06-01 18:34:26 -07:00
Victor Woeltjen
cb9231f453 [Imagery] Set up test mocks 2017-06-01 18:16:15 -07:00
Victor Woeltjen
1c9230029d [Imagery] Begin updating spec 2017-06-01 15:46:58 -07:00
Victor Woeltjen
e300b49c95 [Imagery] Normalize whitespace in policy 2017-05-31 16:05:57 -07:00
Victor Woeltjen
f6cd35a631 [Imagery] Fix code style issues in spec 2017-05-31 16:04:56 -07:00
Victor Woeltjen
53cecb8909 [Imagery] Add missing semicolon, remove unused vars 2017-05-31 16:02:12 -07:00
Victor Woeltjen
95188f6ce6 [Documentation] Document image hint 2017-05-31 15:57:20 -07:00
Victor Woeltjen
8c7e8dab8e [Imagery] Use consistent field name 2017-05-31 15:52:15 -07:00
Tomáš Stankovič
305d2f60d0 [Build] Include version information in openmct.js 2017-05-31 09:35:55 +02:00
Dhrubomoy Das Gupta
7cdb8db775 [Autocomplete] Hide options if clicked elsewhere. 2017-05-30 23:14:05 -04:00
dhrubomoy
7f14397262 [CLOCK] Issue #1273 : Use '$ scope.field' to avoid hard-coding. 2017-05-30 16:20:12 -04:00
Dhrubomoy Das Gupta
893e24ff98 [CLOCK] Issue #1273 : Allow clock to set timezone with autocomplete dropdown option. 2017-05-28 20:21:52 -04:00
Pete Richards
b60eb6d6ae WIP refactor for new telem api 2017-05-22 18:30:01 -07:00
Pete Richards
26a7fee869 Convert example imagery to plugin 2017-05-22 14:48:12 -07:00
Victor Woeltjen
1bdc0497c7 Merge pull request #1437 from nasa/view-large
[Layout] Add view large button for zooming
2017-05-19 16:29:19 -05:00
Pete Richards
04c2eac9ef [Layout] Add view large button for zooming
Fixes #1437
Markup and CSS for `view large` button in frame context;
Sass formatting cleanups; removed unused styles from
_layout.scss; mods to MCTTriggerModal.js to remove
button label functionality;

Added new "icon-expand" glyph and class;

Fixes #1437
Fixes #1423
New overlay > l-dialog and l-large-view classes;
Fix context-menu z-index to allow context menu
to appear in the overlay;
.object-top-bar refactored and replaced with
.object-browse-bar;
frame > hover now only displays local controls for
proper level, handles nested layout situation;
Fixed font-weight display issues;
MCTTriggerModal.js modified to do the following:
- Remove .frame classes when displaying object in overlay
- Allow click on this overlay .blocker to dismiss overlay

Fixed min-width issue incorrectly targeting .object-browse-bar in frame context;

Added expand anim to large view holder;
Changed close button icon

Significant mobile styling and cleanups;
Markup mods for overlay.html;
Handles dialog on top of large view;
Form validation now displays better in mobile;
Updated /src/api/ui/dialog.html to be in-line
with /platform/commonUI/dialog/res/templates/overlay.html;
Moved border-radius from containerBase to btnBase mixins;

Animate with scale for GPU acceleration

Change desktop animation to use scale, so that it is hardware
accelerated and buttery smooth.  Also fixes text anti-aliasing
to improve readability.

Moved mobile/overlay/_overlay.scss styles into
overlay/_overlay.scss; removed mobile/overlay/_overlay.scss;
Cleanups in _overlay.scss; restored max-width/max-height
to dialogs (removed in #1376 for #1298) and added
min-width;

[Frontend] Mobile fixes in overlay and related

Fixes #1437
Added mobile-specific styling to _messages.scss;
Fixed button layout and margins in _overlay.scss;
Fixed message.html to not default to major style
buttons;

[Frontend] Timing tweaks

Fixes #1437
Moved large view expand transition duration
into theme _constants files; shortened anim
duration

Fix Style errors

[mctTriggerModal] correct scope for toggle

Correct scope for toggleFunction such that #1503 no longer occurs.

Fixes #1503

[Style] Add copyright header
2017-05-18 18:18:19 -07:00
Victor Woeltjen
5daaae36bc Merge pull request #1589 from nasa/protractor-cleanup
[README] Remove reference to protractor
2017-05-18 18:04:08 -05:00
Pete Richards
3dea30b1e1 [README] Remove reference to protractor
Since protractor was removed, remove references in readme.
2017-05-18 15:56:43 -07:00
Victor Woeltjen
9f8578d79e Merge pull request #1586 from nasa/correct-format-updates
[TC] Update format on timesystem change
2017-05-18 15:01:19 -05:00
Victor Woeltjen
0fa5609396 Merge pull request #1587 from nasa/fix-search-indexing
[Search] Use new composition in search
2017-05-18 14:49:47 -05:00
Pete Richards
9956ce31e5 [Search] Use new composition in search
Use private parts of new composition API for generic search indexer
so that all objects are properly accessible in search results.

Also prevent ROOT object from getting indexed but still traverse
composition.  That way, "The root object" no longer shows in search
results.

Update tests to cover changes.

Fixes #1579
2017-05-18 08:51:44 -07:00
Pete Richards
25ff430368 [TC] Update format on timesystem change
Update the format when the timesystem changes.

Fixes https://github.com/nasa/openmct/issues/1585
2017-05-17 18:08:48 -07:00
Victor Woeltjen
cc9a2cbf4f Merge pull request #1584 from nasa/fix-tc-menu
[TC] Fix clock option selection
2017-05-17 13:41:01 -07:00
Pete Richards
cd8c0fa72f [TC] Fix clock option selection 2017-05-17 13:12:36 -07:00
Pete Richards
fff75d111e Merge pull request #1583 from nasa/time-defaults
Time defaults
2017-05-16 17:32:04 -07:00
Pete Richards
f4df84bfa1 [Style] correct style 2017-05-16 17:26:29 -07:00
Pete Richards
0dc65f5dfb [Style] Remove trailing commas
Remove trailing commas that snuck through in #1564.
2017-05-16 15:12:37 -07:00
Pete Richards
6e4abcfed8 [Style] Fix style 2017-05-16 15:08:05 -07:00
Pete Richards
e2f9a0c9cd [dev] proper realtime in dev environment
In dev environment, use proper realtime with a clock.
2017-05-16 14:58:46 -07:00
Pete Richards
749a2ba088 [Docs] Update Time API docs
Update time API docs to accurately reflect usage of the time API.
2017-05-16 14:56:56 -07:00
Pete Richards
b70501a7ed [Time] conditional timeSystem change without bounds
Allow timeSystem to be changed without specifying bounds when
a clock is present and can provide bounds.  This simplifies
bootstrap code.

https://github.com/nasa/openmct/issues/1581
2017-05-16 14:31:20 -07:00
Pete Richards
b8ae741969 [Conductor] remove misleading error
When a menu option that specified an invalid time system with a
clock, the time conductor controller would log an error claiming
that the clock was unknown when in fact the time system is the
culprit.

Remove the error message as the plugin handles this validation
already.   Also removed some unused code.

https://github.com/nasa/openmct/issues/1580
2017-05-16 14:13:08 -07:00
Pete Richards
9f32b4b9cd [Spec] Update spec for new usage
Add a test for new bounds setting behavior, update other tests
to provide correct mocks for new usage of APIs.

https://github.com/nasa/openmct/issues/1582
2017-05-16 13:49:12 -07:00
Pete Richards
fbf736aaf7 [Conductor] improve validation, properly set defaults
Update conductor validation logic to trigger easier-to-understand
error messages for bad configurations.

Update default-setting-behavior to properly set clock and offsets
when the default option is clock-based menu option.

Only set defaults when timeSystem has not already been configured.

fixes https://github.com/nasa/openmct/issues/1580
2017-05-16 13:07:17 -07:00
Pete Richards
344a325cb5 [Time] Tick when clock set
Update time API to tick immediately after setting a clock using
the currentValue of the clock.  This ensures that bounds will
be set when the clock is set, instead of waiting for the next
tick to occur.

fixes https://github.com/nasa/openmct/issues/1582
2017-05-16 12:39:16 -07:00
Pete Richards
eb7f78799d Merge pull request #1564 from ivikash/chore/unused_varibales
chore: Remove unsed variables from codebase
2017-05-16 10:36:44 -07:00
Vikash Agrawal
57d3965fa6 chore: Remove unsed variables from codebase 2017-05-16 08:55:21 +05:30
Victor Woeltjen
2df999ef75 Merge pull request #1575 from nasa/guaranteed-request-properties
[Telem] ensure request has minimum fields
2017-05-15 12:08:55 -07:00
Victor Woeltjen
c2cd0db9a3 Merge pull request #1576 from nasa/separate-formats-from-timesystem
Separate formats from timesystem
2017-05-15 12:06:05 -07:00
Pete Richards
04305b7fe5 Merge pull request #1577 from nasa/tc-err-msg
[Time Conductor] Fix link in error message
2017-05-15 11:28:06 -07:00
Victor Woeltjen
d2f13354a7 [Time Conductor] Fix link in error message 2017-05-12 12:31:38 -07:00
Pete Richards
a9067892f4 [Docs] Update format docs
Remove examples of format implementations.  The docs stated
incorrectly that UTCTimeFormat used the additional parameters
for the format method when it did not actually use those
parameters.

With our current landscape of telemetry providers, parse can
frequently be called on an already parsed value, so added
documentation to highlight the importance of an idempotent
parse method.

Cleanup related to change of file locations in:
https://github.com/nasa/openmct/issues/1574
2017-05-10 17:47:14 -07:00
Pete Richards
88223f5e6d [Time] Always include basic formats
Always include basic formats; removing them from the utc format
bundle.  This way, they can be utilized by third parties without
them having to commit to the utc time system.

Fixes https://github.com/nasa/openmct/issues/1574
2017-05-10 17:41:25 -07:00
Pete Richards
6310be623a [Telem] ensure request has minimum fields
Ensure telemetry request options always have a certain number
of fields-- start, end, and domain.  This allows telemetry providers
to implement necessary filtering for these types of requests.
2017-05-10 17:22:01 -07:00
Victor Woeltjen
6481ddbd7f Merge pull request #1573 from nasa/we-dont-depreciate
[Typo] Fix deprecation warning
2017-05-10 14:54:37 -07:00
Pete Richards
258020624c Merge pull request #1571 from nasa/standardize-type-name
[Types] label -> name
2017-05-10 14:51:25 -07:00
Victor Woeltjen
29d65e9cef Merge pull request #1547 from nasa/no-error-on-root-load
[Browse] Handle missing path and nav to root
2017-05-10 14:51:07 -07:00
Pete Richards
31a605c153 [Typo] Fix deprecation warning
we don't depreciate... we deprecate code.
2017-05-10 14:48:55 -07:00
Pete Richards
08a8207f64 Correct Typo, check with hasOwnProperty
Update warning message with correct wording, and change
check for label property such that a blank label will also
trigger the deprecation warning.

Addresses feedback from https://github.com/nasa/openmct/pull/1571
2017-05-10 14:39:47 -07:00
Victor Woeltjen
5a9ca08984 Merge pull request #1572 from nasa/standardize-value-hints
Standardize value hints
2017-05-10 13:43:42 -07:00
Pete Richards
0a3d51c6b5 [Telem] add backwards compat and warning
Add backwards compatibility for x/y hints, and log a warning to
console when x/y hints are encountered.

Fixes https://github.com/nasa/openmct/issues/1546
2017-05-09 19:20:03 -07:00
Pete Richards
81208d617f [Spec] Update specs for new calls
Update specs to expect 'domain' instead of 'x'.

Fixes https://github.com/nasa/openmct/issues/1546
2017-05-09 19:02:10 -07:00
Pete Richards
7ba83b639a [Sinewave] Remove unused files
Remove unused files in the sinewave generator.
2017-05-09 18:57:40 -07:00
Pete Richards
6c093160c2 [Sinewave] Remove old config
Remove old time conductor configuration that doesn't do anything
in the current version of the application.
2017-05-09 18:55:57 -07:00
Pete Richards
7706109c81 [Sinewave] Get rid of broken format
Not sure what the Delta value was intended to display, but the
format wasn't working as expected (as far as I can tell), so
removed it for simplicity.
2017-05-09 18:54:29 -07:00
Pete Richards
00bebbc66f [Sinewave] Use newstyle metadata
Update sinewave generator to use newstyle metadata.

https://github.com/nasa/openmct/issues/1546
2017-05-09 18:53:15 -07:00
Pete Richards
3df7e30d2c [Telemetry] x/y -> domain/range
Update source to use domain/range instead of x/y.

https://github.com/nasa/openmct/issues/1546
2017-05-09 18:51:57 -07:00
Pete Richards
c674627ebd [Docs] x/y -> domain/range
Update docs to reference domain and range.  Also added additional
documentation for the Telemetry API based on a previous draft of
the docs.

https://github.com/nasa/openmct/issues/1546
2017-05-09 18:36:37 -07:00
Pete Richards
c5161887e2 [Types] label -> name
Change label to name, log a warning to console if a typeDef
is registered with a label.

Fixes https://github.com/nasa/openmct/issues/1568.
2017-05-09 17:55:15 -07:00
Victor Woeltjen
f8a04d0fc2 [Timer] cssclass to cssClass
Along with preceding changes, fixes #623
2017-05-03 16:32:41 -07:00
Victor Woeltjen
6e1a43130d [Timers] Simplify mutation calls 2017-05-03 16:15:17 -07:00
Victor Woeltjen
906646704e Merge remote-tracking branch 'origin/master' into open-623 2017-05-03 16:05:03 -07:00
Victor Woeltjen
4e15d8fa1f Merge pull request #1479 from nasa/open1233a
Review and publish Open MCT Style Guide v1
2017-05-02 12:01:25 -07:00
Pete Richards
1f250dd8e7 Merge pull request #1553 from nasa/time-api-redo
[Time API] V1.0 Time API and associated refactoring
2017-05-01 17:11:19 -07:00
Henry
95202611ea [Time Conductor] Removed redundant getTimeSystem function 2017-05-01 16:55:53 -07:00
Henry
d88e905c65 [Time Conductor] Fixed TOI directive which was not being included 2017-05-01 16:24:34 -07:00
Henry
abb7230231 [Time Conductor] Fixed or disabled failing tests 2017-05-01 16:19:11 -07:00
Henry
92d2ec7cf4 [Time Conductor] Addressing comments from code review 2017-05-01 15:01:24 -07:00
Henry
46a51bd8db [Time API] Fixed static code analysis issues 2017-05-01 13:29:14 -07:00
Pete Richards
6680db0b31 Merge pull request #1551 from nasa/msl-units
[Example] Add units to MSL example.
2017-05-01 13:23:12 -07:00
Henry
9ff602a655 [Example] Updated copyright statement in MSL data dictionary 2017-05-01 13:07:32 -07:00
Henry
37c9c6dfaf [Time Conductor] Made corrections to Time API documentation. Added a key field to the NumberFormat so that it can be used with the new format registration mechanism 2017-05-01 11:27:00 -07:00
Henry
0981e99256 [Time API] Updated API documentation to include new Time API options. 2017-04-30 23:21:48 -07:00
Henry
0793442518 [Time API] Provided 'AddFormat' method for registering new formats 2017-04-30 23:21:13 -07:00
Henry
31897ec520 [Time Conductor] Misc. bug fixes, additional documentation for conductor elements, moved and renamed LAD tick source 2017-04-29 16:02:25 -07:00
Henry
6628f93823 [Time API] Updated documentation for Time API 2017-04-29 16:01:20 -07:00
DJ Johnson
8fb9306272 Merge branch 'master' into open-623 2017-04-29 17:10:27 -05:00
Henry
52b6815687 Removed redundant undefined check, and renamed allTimeSystems to getAllTimeSystems 2017-04-28 16:27:07 -07:00
Henry
f17417a541 [Time API] Modified public Time API to support registration of time systems and clocks, setting of active clock, simplification of clocks and time systems, setting of offsets(deltas) and other changes as per #1265 and #1474. Refactoring of UI code to support changes. 2017-04-28 16:03:59 -07:00
Henry
69b06364eb [Example] Add units to MSL example. Recreates functionality from the old live demo 2017-04-27 19:02:35 -07:00
Andrew Henry
1d7d963a4f Merge pull request #1548 from nasa/no-recursive-mutation-on-composition
[API] track composition before notifying listeners
2017-04-27 14:46:02 -07:00
Pete Richards
910d746002 [API] track composition before notifying listeners
Track the updated composition of an object before notifying any
listeners.  Otherwise, any composition listener that mutates the
object would cause an infinite loop.

Detected in implementation of the new plot.
2017-04-27 14:19:38 -07:00
Pete Richards
f02f1d47f1 [Browse] Handle missing path and nav to root
When no path is specified, don't throw error.  Navigate
to default, as expected.

When navigating to root, navigate to the last child
of root instead.  This handles cases where DEFAULT_PATH
is not found (e.g. deployments without "mine").
2017-04-27 14:14:35 -07:00
Pete Richards
beaf8af2e8 Merge pull request #1544 from nasa/open1543
[Telemetry] Use the 'source' metadata field to retrieve telemetry metadata, if available.
2017-04-27 13:50:04 -07:00
Pete Richards
fce8f13984 Remove check for invalid return, update spec
Remove a check for an invalid return value, update the spec to
return the proper value.  Also updated the subscribe method
to fetch defaults the same as the request method.

https://github.com/nasa/openmct/pull/1544
2017-04-27 13:43:54 -07:00
Andrew Henry
bcdad3f19c Merge pull request #1506 from nasa/table-parse-change
[Table] parse/format with datum
2017-04-27 11:43:40 -07:00
Pete Richards
058dfb0c87 Merge pull request #1490 from nasa/open1482
[Edit] Only persist on mutation if model has actually changed locally
2017-04-27 11:28:11 -07:00
Pete Richards
2b41321c03 [Spec] Update API mock
Update telemetry api mock to return proper value formatters.
2017-04-27 11:20:25 -07:00
Pete Richards
5db03bb1bd [Spec] update formatter mock, remove smelly test
Update the formatter mock to implement the expected methods, such
that formatting occurs properly.

Remove a test that was validating the execution of a method
as this was smelly-- it's not the method that is important, it's
the result (that couldn't be obtained without the method).
2017-04-27 11:15:05 -07:00
Henry
26e13a6cd0 [Telemetry] Use the 'source' metadata field to retrieve telemetry metadata, if available. Fixes #1543. 2017-04-26 21:19:55 -07:00
Henry
00f3b6ce5c Revert "[Telemetry] Use the 'source' metadata field to retrieve telemetry metadata, if available. Fixes #1543."
This reverts commit 11677b97ab.
2017-04-26 21:18:57 -07:00
Henry
11677b97ab [Telemetry] Use the 'source' metadata field to retrieve telemetry metadata, if available. Fixes #1543. 2017-04-26 21:15:52 -07:00
Charles Hacskaylo
281559e84b [Test] Removed example/*.html from karma.conf.js
Fixes #1233
2017-04-26 15:05:35 -07:00
Henry
222f852af4 [Edit] Only persist on mutation if model has actually changed locally. Fixes #1482 2017-04-24 21:35:42 -07:00
DJ
5aa93ba50c [Timer] Back-end code cleanup and removed unused code
Cleaned up code by removing unused and unneeded code and the tests associated with it
2017-04-09 18:40:22 -05:00
Pete Richards
0434928f55 [Table] parse/format with datum
Use formatter to parse format datum such that source remapping
is properly handled.
2017-04-03 09:46:41 -07:00
Charles Hacskaylo
26db493b0d [Frontend] Removed unused var
Fixes #623
Removed stateCssClass, not needed;
2017-01-26 15:27:05 -08:00
Charles Hacskaylo
6459f410e7 [Frontend] Code style cleanups in Timer *spec files
Fixes #623
Moved testState() function placement in code;
Added semicolons;
2017-01-26 15:09:01 -08:00
Charles Hacskaylo
4072b91808 [Frontend] Styling for Timer
Fixes #623
Mod to code to allow timerState to be accessible
to markup; CSS for stop button and paused/stopped states
2017-01-26 11:57:08 -08:00
Charles Hacskaylo
8750bdd778 Merge branch 'open623' of https://github.com/DocJava/openmct into DocJava-open623 2017-01-25 17:17:53 -08:00
DJ
60a8ee657a [Timer] Updated Timer UI and fixed tests
Added peeking stop button to view, added legacy and first run support, added new and fixed old tests
2017-01-25 18:21:52 -06:00
DJ
ecf1bac5c7 [Timer] Updated Timer UI to indicate playing or paused state
Removed PauseCheck & TimeOfPause from properties, Removed duplicate functionality Resume class , replaced peeking restart at 0 button with persistent play/pause button
2017-01-18 07:08:54 -06:00
DJ
d04bdd2685 [Timer] Removed icon-stop
Removed icon-stop, identical to icon-box
2017-01-17 19:55:32 -06:00
DJ
165bd4f638 [Clocks / Timers]  adding ability to pause and resume
added the alternating pause and resume timer
2017-01-14 16:43:20 -06:00
DJ
9df59522d9 [Clocks / Timers]  adding ability to stop
added the stop timer menu option
2017-01-14 16:42:44 -06:00
DJ
7fc66e2de8 [Clocks/Timers] renaming of Abstract class
renaming AbstractStartTimerAction to AbstractTime
2017-01-14 16:41:54 -06:00
249 changed files with 10652 additions and 4854 deletions

2
.gitignore vendored
View File

@@ -36,3 +36,5 @@ protractor/logs
# npm-debug log
npm-debug.log
package-lock.json

743
API.md
View File

@@ -3,42 +3,45 @@
## Scope and purpose of this document
This document is intended to serve as a reference for developing an application
based on Open MCT. It will provide details of the API functions necessary to extend the
Open MCT platform meet common use cases such as integrating with a telemetry source.
based on Open MCT. It will provide details of the API functions necessary to
extend the Open MCT platform meet common use cases such as integrating with a telemetry source.
The best place to start is with the [Open MCT Tutorials](https://github.com/nasa/openmct-tutorial).
These will walk you through the process of getting up and running with Open MCT,
as well as addressing some common developer use cases.
These will walk you through the process of getting up and running with Open
MCT, as well as addressing some common developer use cases.
## Building From Source
The latest version of Open MCT is available from [our GitHub repository](https://github.com/nasa/openmct).
If you have `git`, and `node` installed, you can build Open MCT with the commands
```
If you have `git`, and `node` installed, you can build Open MCT with the
commands
```bash
git clone https://github.com/nasa/openmct.git
cd openmct
npm install
```
These commands will fetch the Open MCT source from our GitHub repository, and build
a minified version that can be included in your application. The output of the
build process is placed in a `dist` folder under the openmct source directory,
which can be copied out to another location as needed. The contents of this
folder will include a minified javascript file named `openmct.js` as well as
assets such as html, css, and images necessary for the UI.
These commands will fetch the Open MCT source from our GitHub repository, and
build a minified version that can be included in your application. The output
of the build process is placed in a `dist` folder under the openmct source
directory, which can be copied out to another location as needed. The contents
of this folder will include a minified javascript file named `openmct.js` as
well as assets such as html, css, and images necessary for the UI.
## Starting an Open MCT application
To start a minimally functional Open MCT application, it is necessary to include
the Open MCT distributable, enable some basic plugins, and bootstrap the application.
The tutorials walk through the process of getting Open MCT up and running from scratch,
but provided below is a minimal HTML template that includes Open MCT, installs
some basic plugins, and bootstraps the application. It assumes that Open MCT is
installed under an `openmct` subdirectory, as described in [Building From Source](#building-from-source).
To start a minimally functional Open MCT application, it is necessary to
include the Open MCT distributable, enable some basic plugins, and bootstrap
the application. The tutorials walk through the process of getting Open MCT up
and running from scratch, but provided below is a minimal HTML template that
includes Open MCT, installs some basic plugins, and bootstraps the application.
It assumes that Open MCT is installed under an `openmct` subdirectory, as
described in [Building From Source](#building-from-source).
This approach includes openmct using a simple script tag, resulting in a global
variable named `openmct`. This `openmct` object is used subsequently to make API
calls.
variable named `openmct`. This `openmct` object is used subsequently to make
API calls.
Open MCT is packaged as a UMD (Universal Module Definition) module, so common
script loaders are also supported.
@@ -63,18 +66,19 @@ script loaders are also supported.
</html>
```
The Open MCT library included above requires certain assets such as html templates,
images, and css. If you installed Open MCT from GitHub as described in the section
on [Building from Source](#building-from-source) then these assets will have been
downloaded along with the Open MCT javascript library. You can specify the
location of these assets by calling `openmct.setAssetPath()`. Typically this will
be the same location as the `openmct.js` library is included from.
The Open MCT library included above requires certain assets such as html
templates, images, and css. If you installed Open MCT from GitHub as described
in the section on [Building from Source](#building-from-source) then these
assets will have been downloaded along with the Open MCT javascript library.
You can specify the location of these assets by calling `openmct.setAssetPath()`.
Typically this will be the same location as the `openmct.js` library is
included from.
There are some plugins bundled with the application that provide UI, persistence,
and other default configuration which are necessary to be able to do anything with
the application initially. Any of these plugins can, in principle, be replaced with a custom
plugin. The included plugins are documented in the [Included Plugins](#included-plugins)
section.
There are some plugins bundled with the application that provide UI,
persistence, and other default configuration which are necessary to be able to
do anything with the application initially. Any of these plugins can, in
principle, be replaced with a custom plugin. The included plugins are
documented in the [Included Plugins](#included-plugins) section.
## Plugins
@@ -87,25 +91,28 @@ openmct.install(function install(openmctAPI) {
});
```
New plugins are installed in Open MCT by calling `openmct.install`, and providing
a plugin installation function. This function will be invoked on application
startup with one parameter - the openmct API object. A common approach used in
the Open MCT codebase is to define a plugin as a function that returns this
installation function. This allows configuration to be specified when the plugin is included.
New plugins are installed in Open MCT by calling `openmct.install`, and
providing a plugin installation function. This function will be invoked on
application startup with one parameter - the openmct API object. A common
approach used in the Open MCT codebase is to define a plugin as a function that
returns this installation function. This allows configuration to be specified
when the plugin is included.
eg.
```javascript
openmct.install(openmct.plugins.Elasticsearch("http://localhost:8002/openmct"));
```
This approach can be seen in all of the [plugins provided with Open MCT](https://github.com/nasa/openmct/blob/master/src/plugins/plugins.js).
## Domain Objects and Identifiers
_Domain Objects_ are the basic entities that represent domain knowledge in Open MCT.
The temperature sensor on a solar panel, an overlay plot comparing
the results of all temperature sensors, the command dictionary for a spacecraft,
the individual commands in that dictionary, the "My Items" folder:
All of these things are domain objects.
_Domain Objects_ are the basic entities that represent domain knowledge in Open
MCT. The temperature sensor on a solar panel, an overlay plot comparing the
results of all temperature sensors, the command dictionary for a spacecraft,
the individual commands in that dictionary, the "My Items" folder: All of these
things are domain objects.
A _Domain Object_ is simply a javascript object with some standard attributes.
An example of a _Domain Object_ is the "My Items" object which is a folder in
@@ -128,25 +135,27 @@ looks like this:
### Object Attributes
The main attributes to note are the `identifier`, and `type` attributes.
* `identifier`: A composite key that provides a universally unique identifier for
this object. The `namespace` and `key` are used to identify the object. The `key`
must be unique within the namespace.
* `identifier`: A composite key that provides a universally unique identifier
for this object. The `namespace` and `key` are used to identify the object.
The `key` must be unique within the namespace.
* `type`: All objects in Open MCT have a type. Types allow you to form an
ontology of knowledge and provide an abstraction for grouping, visualizing, and
interpreting data. Details on how to define a new object type are provided below.
ontology of knowledge and provide an abstraction for grouping, visualizing,
and interpreting data. Details on how to define a new object type are
provided below.
Open MCT uses a number of builtin types. Typically you are going to want to
define your own if extending Open MCT.
define your own when extending Open MCT.
### Domain Object Types
Custom types may be registered via the `addType` function on the opencmt Type
Custom types may be registered via the `addType` function on the Open MCT Type
registry.
eg.
```javascript
openmct.types.addType('my-type', {
label: "My Type",
name: "My Type",
description: "This is a type that I added!",
creatable: true
});
@@ -157,7 +166,7 @@ The `addType` function accepts two arguments:
for an object.
* An object type specification. An object type definition supports the following
attributes
* `label`: a `string` naming this object type
* `name`: a `string` naming this object type
* `description`: a `string` specifying a longer-form description of this type
* `initialize`: a `function` which initializes the model for new domain objects
of this type. This can be used for setting default values on an object when
@@ -284,116 +293,576 @@ var domainObject = {
};
```
## Telemetry Providers
## Telemetry API
When connecting to a new telemetry source, you will need to register a new
_Telemetry Provider_. A _Telemetry Provider_ retrieves telemetry data from some telemetry
source, and exposes them in a way that can be used by Open MCT. A telemetry
provider typically can support a one off __request__ for a batch of telemetry data,
or it can provide the ability to __subscribe__ to receive new telemetry data when
it becomes available, or both.
The Open MCT telemetry API provides two main sets of interfaces-- one for integrating telemetry data into Open MCT, and another for developing Open MCT visualization plugins utilizing telemetry API.
```javascript
openmct.telemetry.addProvider({
supportsRequest: function (domainObject) {
//...
},
supportsSubscribe: function (domainObject) {
//...
},
request: function (domainObject, options) {
//...
},
subscribe: function (domainObject, callback, options) {
//...
}
})
```
The APIs for visualization plugins are still a work in progress and docs may change at any time. However, the APIs for integrating telemetry metadata into Open MCT are stable and documentation is included below.
A telemetry provider is an object with the following functions defined:
### Integrating Telemetry Sources
* `supportsRequest`: An __optional__ `function` that accepts a
[Domain Object](#domain-objects-and-identifiers) and returns a `boolean` value
indicating whether or not this provider supports telemetry requests for the
given object. If this returns `true` then a `request` function must be defined.
* `supportsSubscribe`: An __optional__ `function` that accepts a
[Domain Object](#domain-objects-and-identifiers) and returns a `boolean` value
indicating whether or not this provider supports telemetry subscriptions. If this
returns `true` then a `subscribe` function must also be defined. As with `request`,
the return value will typically be conditional, and based on attributes of
`domainObject` such as its identifier.
* `request`: A `function` that returns a `Promise` that will resolve with an `Array`
of telemetry in a single query. This function accepts as arguments a
[Domain Object](#domain-objects-and-identifiers) and an object containing some
[request options](#telemetry-requests).
* `subscribe`: A `function` that accepts a [Domain Object](#domain-objects-and-identifiers),
a callback `function`, and a [telemetry request](#telemetry-requests). The
callback is invoked whenever telemetry is available, and
The implementations for `request` and `subscribe` can vary depending on the
nature of the endpoint which will provide telemetry. In the example above,
it is assumed that `myAdapter` contains the implementation details
(such as HTTP requests, WebSocket connections, etc.) associated with some telemetry
source.
There are two main tasks for integrating telemetry sources-- describing telemetry objects with relevant metadata, and then providing telemetry data for those objects. You'll use an [Object Provider](#object-providers) to provide objects with the necessary [Telemetry Metadata](#telemetry-metadata), and then register a [Telemetry Provider](#telemetry-providers) to retrieve telemetry data for those objects.
For a step-by-step guide to building a telemetry adapter, please see the
[Open MCT Tutorials](https://github.com/larkin/openmct-tutorial).
[Open MCT Tutorials](https://github.com/nasa/openmct-tutorial).
### Telemetry Requests
Telemetry requests support time bounded queries. A call to a _Telemetry Provider_'s
`request` function will include an `options` argument. These are simply javascript
objects with attributes for the request parameters. An example of a telemetry
request object with a start and end time is included below:
```javascript
#### Telemetry Metadata
A telemetry object is a domain object with a telemetry property. To take an example from the tutorial, here is the telemetry object for the "fuel" measurement of the spacecraft:
```json
{
start: 1487981997240,
end: 1487982897240
"identifier": {
"namespace": "example.taxonomy",
"key": "prop.fuel"
},
"name": "Fuel",
"type": "example.telemetry",
"telemetry": {
"values": [
{
"key": "value",
"name": "Value",
"units": "kilograms",
"format": "float",
"min": 0,
"max": 100,
"hints": {
"range": 1
}
},
{
"key": "utc",
"source": "timestamp",
"name": "Timestamp",
"format": "utc",
"hints": {
"domain": 1
}
}
]
}
}
```
### Telemetry Data
The most important part of the telemetry metadata is the `values` property-- this describes the attributes of telemetry datums (objects) that a telemetry provider returns. These descriptions must be provided for telemetry views to work properly.
Telemetry data is provided to Open MCT by _[Telemetry Providers](#telemetry-providers)_
in the form of javascript objects. A collection of telemetry values (for example,
retrieved in response to a `request`) is represented by an `Array` of javascript
objects. These telemetry javascript objects are simply key value pairs.
##### Values
Typically a telemetry datum will have some timestamp associated with it. This
time stamp should have a key that corresponds to some time system supported by
Open MCT. If the `UTCTimeSystem` plugin is installed, then the key `utc` can be used.
An example of a telemetry provider request function that returns a collection of
mock telemtry data is below:
`telemetry.values` is an array of value description objects, which have the following fields:
attribute | type | flags | notes
--- | --- | --- | ---
`key` | string | required | unique identifier for this field.
`hints` | object | required | Hints allow views to intelligently select relevant attributes for display, and are required for most views to function. See section on "Value Hints" below.
`name` | string | optional | a human readible label for this field. If omitted, defaults to `key`.
`source` | string | optional | identifies the property of a datum where this value is stored. If omitted, defaults to `key`.
`format` | string | optional | a specific format identifier, mapping to a formatter. If omitted, uses a default formatter. For enumerations, use `enum`. For timestamps, use `utc` if you are using utc dates, otherwise use a key mapping to your custom date format.
`units` | string | optional | the units of this value, e.g. `km`, `seconds`, `parsecs`
`min` | number | optional | the minimum possible value of this measurement. Will be used by plots, gauges, etc to automatically set a min value.
`max` | number | optional | the maximum possible value of this measurement. Will be used by plots, gauges, etc to automatically set a max value.
`enumerations` | array | optional | for objects where `format` is `"enum"`, this array tracks all possible enumerations of the value. Each entry in this array is an object, with a `value` property that is the numerical value of the enumeration, and a `string` property that is the text value of the enumeration. ex: `{"value": 0, "string": "OFF"}`. If you use an enumerations array, `min` and `max` will be set automatically for you.
###### Value Hints
Each telemetry value description has an object defining hints. Keys in this this object represent the hint itself, and the value represents the weight of that hint. A lower weight means the hint has a higher priority. For example, multiple values could be hinted for use as the y axis of a plot (raw, engineering), but the highest priority would be the default choice. Likewise, a table will use hints to determine the default order of columns.
Known hints:
* `domain`: Indicates that the value represents the "input" of a datum. Values with a `domain` hint will be used for the x-axis of a plot, and tables will render columns for these values first.
* `range`: Indicates that the value is the "output" of a datum. Values with a `range` hint will be used as the y-axis on a plot, and tables will render columns for these values after the `domain` values.
* `image`: Indicates that the value may be interpreted as the URL to an image file, in which case appropriate views will be made available.
##### The Time Conductor and Telemetry
Open MCT provides a number of ways to pivot through data and link data via time. The Time Conductor helps synchronize multiple views around the same time.
In order for the time conductor to work, there will always be an active "time system". All telemetry metadata *must* have a telemetry value with a `key` that matches the `key` of the active time system. You can use the `source` attribute on the value metadata to remap this to a different field in the telemetry datum-- especially useful if you are working with disparate datasources that have different field mappings.
#### Telemetry Providers
Telemetry providers are responsible for providing historical and real time telemetry data for telemetry objects. Each telemetry provider determines which objects it can provide telemetry for, and then must implement methods to provide telemetry for those objects.
A telemetry provider is a javascript object with up to four methods:
* `supportsSubscribe(domainObject, callback, options)` optional. Must be implemented to provide realtime telemetry. Should return `true` if the provider supports subscriptions for the given domain object (and request options).
* `subscribe(domainObject, callback, options)` required if `supportsSubscribe` is implemented. Establish a subscription for realtime data for the given domain object. Should invoke `callback` with a single telemetry datum every time data is received. Must return an unsubscribe function. Multiple views can subscribe to the same telemetry object, so it should always return a new unsubscribe function.
* `supportsRequest(domainObject, options)` optional. Must be implemented to provide historical telemetry. Should return `true` if the provider supports historical requests for the given domain object.
* `request(domainObject, options)` required if `supportsRequest` is implemented. Must return a promise for an array of telemetry datums that fulfills the request. The `options` argument will include a `start`, `end`, and `domain` attribute representing the query bounds. For more request properties, see Request Properties below.
Telemetry providers are registered by calling `openmct.telemetry.addProvider(provider)`, e.g.
```javascript
openmct.telemetry.addProvider({
supportsRequest: function (domainObject) {
return true
},
request: function (domainObject, options) {
return Promise.resolve([
{
'utc': Date.now() - 2000,
'value': 1,
},
{
'utc': Date.now() - 1000,
'value': 2,
},
{
'utc': Date.now(),
'value': 3,
}
]);
}
supportsRequest: function (domainObject, options) { /*...*/ },
request: function (domainObject, options) { /*...*/ },
supportsSubscribe: function (domainObject, callback, options) { /*...*/ },
subscribe: function (domainObject, callback, options) { /*...*/ }
})
```
#### Telemetry Requests
Telemetry requests support time bounded queries. A call to a _Telemetry Provider_'s `request` function will include an `options` argument. These are simply javascript objects with attributes for the request parameters. An example of a telemetry request object with a start and end time is included below:
```javascript
{
start: 1487981997240,
end: 1487982897240,
domain: 'utc'
}
```
#### Telemetry Formats
Telemetry format objects define how to interpret and display telemetry data.
They have a simple structure:
* `key`: A `string` that uniquely identifies this formatter.
* `format`: A `function` that takes a raw telemetry value, and returns a
human-readable `string` representation of that value. It has one required
argument, and three optional arguments that provide context and can be used
for returning scaled representations of a value. An example of this is
representing time values in a scale such as the time conductor scale. There
are multiple ways of representing a point in time, and by providing a minimum
scale value, maximum scale value, and a count, it's possible to provide more
useful representations of time given the provided limitations.
* `value`: The raw telemetry value in its native type.
* `minValue`: An __optional__ argument specifying the minimum displayed
value.
* `maxValue`: An __optional__ argument specifying the maximum displayed
value.
* `count`: An __optional__ argument specifying the number of displayed
values.
* `parse`: A `function` that takes a `string` representation of a telemetry
value, and returns the value in its native type. **Note** parse might receive an already-parsed value. This function should be idempotent.
* `validate`: A `function` that takes a `string` representation of a telemetry
value, and returns a `boolean` value indicating whether the provided string
can be parsed.
##### Registering Formats
Formats are registered with the Telemetry API using the `addFormat` function. eg.
``` javascript
openmct.telemetry.addFormat({
key: 'number-to-string',
format: function (number) {
return number + '';
},
parse: function (text) {
return Number(text);
},
validate: function (text) {
return !isNaN(text);
}
});
```
#### Telemetry Data
A single telemetry point is considered a Datum, and is represented by a standard
javascript object. Realtime subscriptions (obtained via __subscribe__) will
invoke the supplied callback once for each telemetry datum recieved. Telemetry
requests (obtained via __request__) will return a promise for an array of
telemetry datums.
##### Telemetry Datums
A telemetry datum is a simple javascript object, e.g.:
```json
{
"timestamp": 1491267051538,
"value": 77,
"id": "prop.fuel"
}
```
The key-value pairs of this object are described by the telemetry metadata of
a domain object, as discussed in the [Telemetry Metadata](#telemetry-metadata)
section.
## Time API
Open MCT provides API for managing the temporal state of the application.
Central to this is the concept of "time bounds". Views in Open MCT will
typically show telemetry data for some prescribed date range, and the Time API
provides a way to centrally manage these bounds.
The Time API exposes a number of methods for querying and setting the temporal
state of the application, and emits events to inform listeners when the state changes.
Because the data displayed tends to be time domain data, Open MCT must always
have at least one time system installed and activated. When you download Open
MCT, it will be pre-configured to use the UTC time system, which is installed and activated, along with other default plugins, in `index.html`. Installing and activating a time system is simple, and is covered
[in the next section](#defining-and-registering-time-systems).
### Time Systems and Bounds
#### Defining and Registering Time Systems
The time bounds of an Open MCT application are defined as numbers, and a Time
System gives meaning and context to these numbers so that they can be correctly
interpreted. Time Systems are JavaScript objects that provide some information
about the current time reference frame. An example of defining and registering
a new time system is given below:
``` javascript
openmct.time.addTimeSystem({
key: 'utc',
name: 'UTC Time',
cssClass = 'icon-clock',
timeFormat = 'utc',
durationFormat = 'duration',
isUTCBased = true
});
```
The example above defines a new utc based time system. In fact, this time system
is configured and activated by default from `index.html` in the default
installation of Open MCT if you download the source from GitHub. Some details of
each of the required properties is provided below.
* `key`: A `string` that uniquely identifies this time system.
* `name`: A `string` providing a brief human readable label. If the [Time Conductor](#the-time-conductor)
plugin is enabled, this name will identify the time system in a dropdown menu.
* `cssClass`: A class name `string` that will be applied to the time system when
it appears in the UI. This will be used to represent the time system with an icon.
There are a number of built-in icon classes [available in Open MCT](https://github.com/nasa/openmct/blob/master/platform/commonUI/general/res/sass/_glyphs.scss),
or a custom class can be used here.
* `timeFormat`: A `string` corresponding to the key of a registered
[telemetry time format](#telemetry-formats). The format will be used for
displaying discrete timestamps from telemetry streams when this time system is
activated. If the [UTCTimeSystem](#included-plugins) is enabled, then the `utc`
format can be used if this is a utc-based time system
* `durationFormat`: A `string` corresponding to the key of a registered
[telemetry time format](#telemetry-formats). The format will be used for
displaying time ranges, for example `00:15:00` might be used to represent a time
period of fifteen minutes. These are used by the Time Conductor plugin to specify
relative time offsets. If the [UTCTimeSystem](#included-plugins) is enabled,
then the `duration` format can be used if this is a utc-based time system
* `isUTCBased`: A `boolean` that defines whether this time system represents
numbers in UTC terrestrial time.
#### Getting and Setting the Active Time System
Once registered, a time system can be activated by calling `timeSystem` with
the timeSystem `key` or an instance of the time system. If you are not using a
[clock](#clocks), you must also specify valid [bounds](#time-bounds) for the
timeSystem.
```javascript
openmct.time.timeSystem('utc', bounds);
```
A time system can be immediately activated after registration:
```javascript
openmct.time.addTimeSystem(utcTimeSystem);
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
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.
* `start`: A `number` representing a moment in time in the active [Time System](#defining-and-registering-time-systems).
This will be used as the beginning of the time period displayed by time-responsive
telemetry views.
* `end`: A `number` representing a moment in time in the active [Time System](#defining-and-registering-time-systems).
This will be used as the end of the time period displayed by time-responsive
telemetry views.
If invoked with bounds, it will set the new time bounds system-wide. If invoked
without any parameters, it will return the current application-wide time bounds.
``` javascript
const ONE_HOUR = 60 * 60 * 1000;
let now = Date.now();
openmct.time.bounds({start: now - ONE_HOUR, now);
```
To respond to bounds change events, listen for the [`'bounds'`](#time-events)
event.
## Clocks
The Time API can be set to follow a clock source which will cause the bounds
to be updated automatically whenever the clock source "ticks". A clock is simply
an object that supports registration of listeners and periodically invokes its
listeners with a number. Open MCT supports registration of new clock sources that
tick on almost anything. A tick occurs when the clock invokes callback functions
registered by its listeners with a new time value.
An example of a clock source is the [LocalClock](https://github.com/nasa/openmct/blob/master/src/plugins/utcTimeSystem/LocalClock.js)
which emits the current time in UTC every 100ms. Clocks can tick on anything. For
example, a clock could be defined to provide the timestamp of any new data
received via a telemetry subscription. This would have the effect of advancing
the bounds of views automatically whenever data is received. A clock could also
be defined to tick on some remote timing source.
The values provided by clocks are simple `number`s, which are interpreted in the
context of the active [Time System](#defining-and-registering-time-systems).
### Defining and registering clocks
A clock is an object that defines certain required metadata and functions:
* `key`: A `string` uniquely identifying this clock. This can be used later to
reference the clock in places such as the [Time Conductor configuration](#time-conductor-configuration)
* `cssClass`: A `string` identifying a CSS class to apply to this clock when it's
displayed in the UI. This will be used to represent the time system with an icon.
There are a number of built-in icon classes [available in Open MCT](https://github.com/nasa/openmct/blob/master/platform/commonUI/general/res/sass/_glyphs.scss),
or a custom class can be used here.
* `name`: A `string` providing a human-readable identifier for the clock source.
This will be displayed in the clock selector menu in the Time Conductor UI
component, if active.
* `description`: An __optional__ `string` providing a longer description of the
clock. The description will be visible in the clock selection menu in the Time
Conductor plugin.
* `on`: A `function` supporting registration of a new callback that will be
invoked when the clock next ticks. It will be invoked with two arguments:
* `eventName`: A `string` specifying the event to listen on. For now, clocks
support one event - `tick`.
* `callback`: A `function` that will be invoked when this clock ticks. The
function must be invoked with one parameter - a `number` representing a valid
time in the current time system.
* `off`: A `function` that allows deregistration of a tick listener. It accepts
the same arguments as `on`.
* `currentValue`: A `function` that returns a `number` representing a point in
time in the active time system. It should be the last value provided by a tick,
or some default value if no ticking has yet occurred.
A new clock can be registered using the `addClock` function exposed by the Time
API:
```javascript
var someClock = {
key: 'someClock',
cssClass: 'icon-clock',
name: 'Some clock',
description: "Presumably does something useful",
on: function (event, callback) {
// Some function that registers listeners, and updates them on a tick
},
off: function (event, callback) {
// Some function that unregisters listeners.
},
currentValue: function () {
// A function that returns the last ticked value for the clock
}
}
openmct.time.addClock(someClock);
```
An example clock implementation is provided in the form of the [LocalClock](https://github.com/nasa/openmct/blob/master/src/plugins/utcTimeSystem/LocalClock.js)
#### Getting and setting active clock
Once registered a clock can be activated by calling the `clock` function on the
Time API passing in the key or instance of a registered clock. Only one clock
may be active at once, so activating a clock will deactivate any currently
active clock. [`clockOffsets`](#clock-offsets) must be specified when changing a clock.
Setting the clock triggers a [`'clock'`](#time-events) event, followed by a [`'clockOffsets'`](#time-events) event, and then a [`'bounds'`](#time-events) event as the offsets are applied to the clock's currentValue().
```
openmct.time.clock(someClock, clockOffsets);
```
Upon being activated, the time API will listen for tick events on the clock by calling `clock.on`.
The currently active clock (if any) can be retrieved by calling the same
function without any arguments.
#### Stopping an active clock
The `stopClock` method can be used to stop an active clock, and to clear it. It
will stop the clock from ticking, and set the active clock to `undefined`.
``` javascript
openmct.time.stopClock();
```
#### Clock Offsets
When a clock is active, the time bounds of the application will be updated
automatically each time the clock "ticks". The bounds are calculated based on
the current value provided by the active clock (via its `tick` event, or its
`currentValue()` method).
Unlike bounds, which represent absolute time values, clock offsets represent
relative time spans. Offsets are defined as an object with two properties:
* `start`: A `number` that must be < 0 and which is used to calculate the start
bounds on each clock tick. The start offset will be calculated relative to the
value provided by a clock's tick callback, or its `currentValue()` function.
* `end`: A `number` that must be >= 0 and which is used to calculate the end
bounds on each clock tick.
The `clockOffsets` function can be used to get or set clock offsets. For example,
to show the last fifteen minutes in a ms-based time system:
```javascript
var FIFTEEN_MINUTES = 15 * 60 * 1000;
openmct.time.clockOffsets({
start: -FIFTEEN_MINUTES,
end: 0
})
```
__Note:__ Setting the clock offsets will trigger an immediate bounds change, as
new bounds will be calculated based on the `currentValue()` of the active clock.
Clock offsets are only relevant when a clock source is active.
## Time Events
The Time API is a standard event emitter; you can register callbacks for events using the `on` method and remove callbacks for events with the `off` method.
For example:
``` javascript
openmct.time.on('bounds', function callback (newBounds, tick) {
// Do something with new bounds
});
```
#### List of Time Events
The events emitted by the Time API are:
* `bounds`: emitted whenever the bounds change. The callback will be invoked
with two arguments:
* `bounds`: A [bounds](#getting-and-setting-bounds) bounds object
representing a new time period bound by the specified start and send times.
* `tick`: A `boolean` indicating whether or not this bounds change is due to
a "tick" from a [clock source](#clocks). This information can be useful
when determining a strategy for fetching telemetry data in response to a
bounds change event. For example, if the bounds change was automatic, and
is due to a tick then it's unlikely that you would need to perform a
historical data query. It should be sufficient to just show any new
telemetry received via subscription since the last tick, and optionally to
discard any older data that now falls outside of the currently set bounds.
If `tick` is false,then the bounds change was not due to an automatic tick,
and a query for historical data may be necessary, depending on your data
caching strategy, and how significantly the start bound has changed.
* `timeSystem`: emitted whenever the active time system changes. The callback will be invoked with a single argument:
* `timeSystem`: The newly active [time system](#defining-and-registering-time-systems).
* `clock`: emitted whenever the clock changes. The callback will be invoked
with a single argument:
* `clock`: The newly active [clock](#clocks), or `undefined` if an active
clock has been deactivated.
* `clockOffsets`: emitted whenever the active clock offsets change. The
callback will be invoked with a single argument:
* `clockOffsets`: The new [clock offsets](#clock-offsets).
## The Time Conductor
The Time Conductor provides a user interface for managing time bounds in Open
MCT. It allows a user to select from configured time systems and clocks, and to set bounds and clock offsets.
If activated, the time conductor must be provided with configuration options,
detailed below.
#### Time Conductor Configuration
The time conductor is configured by specifying the options that will be
available to the user from the menus in the time conductor. These will determine
the clocks available from the conductor, the time systems available for each
clock, and some default bounds and clock offsets for each combination of clock
and time system. By default, the conductor always supports a `fixed` mode where
no clock is active. To specify configuration for fixed mode, simply leave out a
`clock` attribute in the configuration entry object.
Configuration is provided as an `array` of menu options. Each entry of the
array is an object with some properties specifying configuration. The configuration
options specified are slightly different depending on whether or not it is for
an active clock mode.
__Configuration for Fixed Time Mode (no active clock)__
* `timeSystem`: A `string`, the key for the time system that this configuration
relates to.
* `bounds`: A [`Time Bounds`](#time-bounds) object. These bounds will be applied
when the user selects the time system specified in the previous `timeSystem`
property.
* `zoomOutLimit`: An __optional__ `number` specifying the longest period of time
that can be represented by the conductor when zooming. If a `zoomOutLimit` is
provided, then a `zoomInLimit` must also be provided. If provided, the zoom
slider will automatically become available in the Time Conductor UI.
* `zoomInLimit`: An __optional__ `number` specifying the shortest period of time
that can be represented by the conductor when zooming. If a `zoomInLimit` is
provided, then a `zoomOutLimit` must also be provided. If provided, the zoom
slider will automatically become available in the Time Conductor UI.
__Configuration for Active Clock__
* `clock`: A `string`, the `key` of the clock that this configuration applies to.
* `timeSystem`: A `string`, the key for the time system that this configuration
relates to. Separate configuration must be provided for each time system that you
wish to be available to users when they select the specified clock.
* `clockOffsets`: A [`clockOffsets`](#clock-offsets) object that will be
automatically applied when the combination of clock and time system specified in
this configuration is selected from the UI.
#### Example conductor configuration
An example time conductor configuration is provided below. It sets up some
default options for the [UTCTimeSystem](https://github.com/nasa/openmct/blob/master/src/plugins/utcTimeSystem/UTCTimeSystem.js)
and [LocalTimeSystem](https://github.com/nasa/openmct/blob/master/src/plugins/localTimeSystem/LocalTimeSystem.js),
in both fixed mode, and for the [LocalClock](https://github.com/nasa/openmct/blob/master/src/plugins/utcTimeSystem/LocalClock.js)
source. In this configutation, the local clock supports both the UTCTimeSystem
and LocalTimeSystem. Configuration for fixed bounds mode is specified by omitting
a clock key.
``` javascript
const ONE_YEAR = 365 * 24 * 60 * 60 * 1000;
const ONE_MINUTE = 60 * 1000;
openmct.install(openmct.plugins.Conductor({
menuOptions: [
// 'Fixed' bounds mode configuation for the UTCTimeSystem
{
timeSystem: 'utc',
bounds: {start: Date.now() - 30 * ONE_MINUTE, end: Date.now()},
zoomOutLimit: ONE_YEAR,
zoomInLimit: ONE_MINUTE
},
// Configuration for the LocalClock in the UTC time system
{
clock: 'local',
timeSystem: 'utc',
clockOffsets: {start: - 30 * ONE_MINUTE, end: 0},
zoomOutLimit: ONE_YEAR,
zoomInLimit: ONE_MINUTE
},
//Configuration for the LocaLClock in the Local time system
{
clock: 'local',
timeSystem: 'local',
clockOffsets: {start: - 15 * ONE_MINUTE, end: 0}
}
]
}));
```
## Included Plugins
Open MCT is packaged along with a few general-purpose plugins:
* `openmct.plugins.Conductor` provides a user interface for working with time
within the application. If activated, configuration must be provided. This is
detailed in the section on [Time Conductor Configuration](#time-conductor-configuration).
* `openmct.plugins.CouchDB` is an adapter for using CouchDB for persistence
of user-created objects. This is a constructor that takes the URL for the
CouchDB database as a parameter, e.g.

View File

@@ -137,20 +137,6 @@ naming convention is otherwise the same.)
When `npm test` is run, test results will be written as HTML to
`target/tests`. Code coverage information is written to `target/coverage`.
### Functional Testing
The tests described above are all at the unit-level; an additional
test suite using [Protractor](https://angular.github.io/protractor/)
is under development, in the `protractor` folder.
To run:
* Install protractor following the instructions above.
* `cd protractor`
* `npm install`
* `npm run all`
# Glossary
Certain terms are used throughout Open MCT with consistent meanings

View File

@@ -22,6 +22,7 @@
"eventemitter3": "^1.2.0",
"lodash": "3.10.1",
"almond": "~0.3.2",
"html2canvas": "^0.4.1"
"html2canvas": "^0.4.1",
"moment-timezone": "^0.5.13"
}
}

View File

@@ -933,9 +933,10 @@ Note that `templateUrl` is not supported for `containers`.
Controls provide options for the `mct-control` directive.
Ten standard control types are included in the forms bundle:
These standard control types are included in the forms bundle:
* `textfield`: An area to enter plain text.
* `textfield`: A text input to enter plain text.
* `numberfield`: A text input to enter numbers.
* `select`: A drop-down list of options.
* `checkbox`: A box which may be checked/unchecked.
* `color`: A color picker.

View File

@@ -1,67 +0,0 @@
/*****************************************************************************
* 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(
['./SinewaveConstants', 'moment'],
function (SinewaveConstants, moment) {
var START_TIME = SinewaveConstants.START_TIME,
FORMAT_REGEX = /^-?\d+:\d+:\d+$/,
SECOND = 1000,
MINUTE = SECOND * 60,
HOUR = MINUTE * 60;
function SinewaveDeltaFormat() {
}
function twoDigit(v) {
return v >= 10 ? String(v) : ('0' + v);
}
SinewaveDeltaFormat.prototype.format = function (value) {
var delta = Math.abs(value - START_TIME),
negative = value < START_TIME,
seconds = Math.floor(delta / SECOND) % 60,
minutes = Math.floor(delta / MINUTE) % 60,
hours = Math.floor(delta / HOUR);
return (negative ? "-" : "") +
[ hours, minutes, seconds ].map(twoDigit).join(":");
};
SinewaveDeltaFormat.prototype.validate = function (text) {
return FORMAT_REGEX.test(text);
};
SinewaveDeltaFormat.prototype.parse = function (text) {
var negative = text[0] === "-",
parts = text.replace("-", "").split(":");
return [ HOUR, MINUTE, SECOND ].map(function (sz, i) {
return parseInt(parts[i], 10) * sz;
}).reduce(function (a, b) {
return a + b;
}, 0) * (negative ? -1 : 1) + START_TIME;
};
return SinewaveDeltaFormat;
}
);

View File

@@ -1,70 +0,0 @@
/*****************************************************************************
* 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 SinewaveTelemetryProvider. Created by vwoeltje on 11/12/14.
*/
define([
"./SinewaveTelemetrySeries",
"./GeneratorProvider"
], function (
SinewaveTelemetrySeries,
GeneratorProvider
) {
function SinewaveTelemetryProvider() {
this.provider = new GeneratorProvider();
}
SinewaveTelemetryProvider.prototype.requestTelemetry = function (requests) {
if (requests[0].source !== 'generator') {
return Promise.resolve({});
}
return this.provider.request({}, requests[0])
.then(function (data) {
var res = {
generator: {}
};
res.generator[requests[0].key] = new SinewaveTelemetrySeries(data);
return res;
});
};
SinewaveTelemetryProvider.prototype.subscribe = function (callback, requests) {
if (requests[0].source !== 'generator') {
return function unsubscribe() {};
}
function wrapper(data) {
var res = {
generator: {}
};
res.generator[requests[0].key] = new SinewaveTelemetrySeries(data);
callback(res);
}
return this.provider.subscribe({}, wrapper, requests[0]);
};
return SinewaveTelemetryProvider;
});

View File

@@ -1,75 +0,0 @@
/*****************************************************************************
* 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 SinewaveTelemetry. Created by vwoeltje on 11/12/14.
*/
define([
], function (
) {
"use strict";
function SinewaveTelemetrySeries(data) {
if (!Array.isArray(data)) {
data = [data];
}
this.data = data;
}
SinewaveTelemetrySeries.prototype.getPointCount = function () {
return this.data.length;
};
SinewaveTelemetrySeries.prototype.getDomainValue = function (
index,
domain
) {
domain = domain || 'time';
return this.getDatum(index)[domain];
};
SinewaveTelemetrySeries.prototype.getRangeValue = function (
index,
range
) {
range = range || 'sin';
return this.getDatum(index)[range];
};
SinewaveTelemetrySeries.prototype.getDatum = function (index) {
if (index > this.data.length || index < 0) {
throw new Error('IndexOutOfRange: index not available in series.');
}
return this.data[index];
};
SinewaveTelemetrySeries.prototype.getData = function () {
return this.data;
};
return SinewaveTelemetrySeries;
});

View File

@@ -64,7 +64,6 @@
data: {
utc: nextStep,
yesterday: nextStep - 60*60*24*1000,
delta: 60*60*24*1000,
sin: sin(nextStep, data.period, data.amplitude, data.offset),
cos: cos(nextStep, data.period, data.amplitude, data.offset)
}
@@ -104,11 +103,10 @@
var data = [];
for (; nextStep < end; nextStep += step) {
for (; nextStep < end && data.length < 5000; nextStep += step) {
data.push({
utc: nextStep,
yesterday: nextStep - 60*60*24*1000,
delta: 60*60*24*1000,
sin: sin(nextStep, period, amplitude, offset),
cos: cos(nextStep, period, amplitude, offset)
});

View File

@@ -23,12 +23,10 @@
define([
"./GeneratorProvider",
"./SinewaveLimitCapability",
"./SinewaveDeltaFormat"
"./SinewaveLimitCapability"
], function (
GeneratorProvider,
SinewaveLimitCapability,
SinewaveDeltaFormat
SinewaveLimitCapability
) {
var legacyExtensions = {
@@ -37,34 +35,8 @@ define([
"key": "limit",
"implementation": SinewaveLimitCapability
}
],
"formats": [
{
"key": "example.delta",
"implementation": SinewaveDeltaFormat
}
],
"constants": [
{
"key": "TIME_CONDUCTOR_DOMAINS",
"value": [
{
"key": "time",
"name": "Time"
},
{
"key": "yesterday",
"name": "Yesterday"
},
{
"key": "delta",
"name": "Delta"
}
],
"priority": -1
}
]
}
};
return function(openmct){
//Register legacy extensions for things not yet supported by the new API
@@ -75,7 +47,7 @@ define([
})
});
openmct.types.addType("generator", {
label: "Sine Wave Generator",
name: "Sine Wave Generator",
description: "For development use. Generates example streaming telemetry data using a simple sine wave algorithm.",
cssClass: "icon-telemetry",
creatable: true,
@@ -135,31 +107,36 @@ define([
amplitude: 1,
offset: 0,
dataRateInHz: 1,
domains: [
values: [
{
key: "utc",
name: "Time",
format: "utc"
format: "utc",
hints: {
domain: 1
}
},
{
key: "yesterday",
name: "Yesterday",
format: "utc"
format: "utc",
hints: {
domain: 2
}
},
{
key: "delta",
name: "Delta",
format: "example.delta"
}
],
ranges: [
{
key: "sin",
name: "Sine"
name: "Sine",
hints: {
range: 1
}
},
{
key: "cos",
name: "Cosine"
name: "Cosine",
hints: {
range: 2
}
}
]
};

View File

@@ -1,80 +0,0 @@
/*****************************************************************************
* 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/ImageTelemetryProvider",
'legacyRegistry'
], function (
ImageTelemetryProvider,
legacyRegistry
) {
"use strict";
legacyRegistry.register("example/imagery", {
"name": "Imagery",
"description": "Example of a component that produces image telemetry.",
"extensions": {
"components": [
{
"implementation": ImageTelemetryProvider,
"type": "provider",
"provides": "telemetryService",
"depends": [
"$q",
"$timeout"
]
}
],
"types": [
{
"key": "imagery",
"name": "Example Imagery",
"cssClass": "icon-image",
"features": "creation",
"description": "For development use. Creates example imagery data that mimics a live imagery stream.",
"priority": 10,
"model": {
"telemetry": {}
},
"telemetry": {
"source": "imagery",
"domains": [
{
"name": "Time",
"key": "time",
"format": "utc"
}
],
"ranges": [
{
"name": "Image",
"key": "url",
"format": "imageUrl"
}
]
}
}
]
}
});
});

140
example/imagery/plugin.js Normal file
View File

@@ -0,0 +1,140 @@
/*****************************************************************************
* 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.
*****************************************************************************/
define([
], function(
) {
function ImageryPlugin() {
var IMAGE_SAMPLES = [
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18731.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18732.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18733.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18734.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18735.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18736.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18737.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18738.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18739.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18740.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18741.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18742.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18743.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18744.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18745.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18746.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18747.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18748.jpg"
];
function pointForTimestamp(timestamp) {
return {
utc: Math.floor(timestamp / 5000) * 5000,
url: IMAGE_SAMPLES[Math.floor(timestamp / 5000) % IMAGE_SAMPLES.length]
};
}
var realtimeProvider = {
supportsSubscribe: function (domainObject) {
return domainObject.type === 'example.imagery';
},
subscribe: function (domainObject, callback) {
var interval = setInterval(function () {
callback(pointForTimestamp(Date.now()));
}, 5000);
return function (interval) {
clearInterval(interval);
};
}
};
var historicalProvider = {
supportsRequest: function (domainObject, options) {
return domainObject.type === 'example.imagery'
&& options.strategy !== 'latest';
},
request: function (domainObject, options) {
var start = options.start;
var end = options.end;
var data = [];
while (start < end && data.length < 5000) {
data.push(pointForTimestamp(start));
start += 5000;
}
return Promise.resolve(data);
}
};
var ladProvider = {
supportsRequest: function (domainObject, options) {
return domainObject.type === 'example.imagery' &&
options.strategy === 'latest';
},
request: function (domainObject, options) {
return Promise.resolve([pointForTimestamp(Date.now())]);
}
};
return function install(openmct) {
openmct.types.addType('example.imagery', {
key: 'example.imagery',
name: 'Example Imagery',
cssClass: 'icon-image',
description: 'For development use. Creates example imagery ' +
'data that mimics a live imagery stream.',
creatable: true,
initialize: function (object) {
object.telemetry = {
values: [
{
name: 'Time',
key: 'utc',
format: 'utc',
hints: {
domain: 1
}
},
{
name: 'Image',
key: 'url',
format: 'image',
hints: {
image: 1
}
}
]
}
}
});
openmct.telemetry.addProvider(realtimeProvider);
openmct.telemetry.addProvider(historicalProvider);
openmct.telemetry.addProvider(ladProvider);
};
}
return ImageryPlugin;
});

View File

@@ -1,81 +0,0 @@
/*****************************************************************************
* 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 ImageTelemetry. Created by vwoeltje on 06/22/15.
*/
define(
[],
function () {
"use strict";
var firstObservedTime = Date.now(),
images = [
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18731.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18732.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18733.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18734.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18735.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18736.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18737.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18738.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18739.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18740.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18741.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18742.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18743.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18744.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18745.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18746.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18747.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18748.jpg"
].map(function (url, index) {
return {
timestamp: firstObservedTime + 1000 * index,
url: url
};
});
/**
*
* @constructor
*/
function ImageTelemetry() {
return {
getPointCount: function () {
return Math.floor((Date.now() - firstObservedTime) / 1000);
},
getDomainValue: function (i, domain) {
return images[i % images.length].timestamp;
},
getRangeValue: function (i, range) {
return images[i % images.length].url;
}
};
}
return ImageTelemetry;
}
);

View File

@@ -1,115 +0,0 @@
/*****************************************************************************
* 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 ImageTelemetryProvider. Created by vwoeltje on 06/22/15.
*/
define(
["./ImageTelemetry"],
function (ImageTelemetry) {
"use strict";
/**
*
* @constructor
*/
function ImageTelemetryProvider($q, $timeout) {
var subscriptions = [];
//
function matchesSource(request) {
return request.source === "imagery";
}
// Used internally; this will be repacked by doPackage
function generateData(request) {
return {
key: request.key,
telemetry: new ImageTelemetry()
};
}
//
function doPackage(results) {
var packaged = {};
results.forEach(function (result) {
packaged[result.key] = result.telemetry;
});
// Format as expected (sources -> keys -> telemetry)
return { imagery: packaged };
}
function requestTelemetry(requests) {
return $timeout(function () {
return doPackage(requests.filter(matchesSource).map(generateData));
}, 0);
}
function handleSubscriptions() {
subscriptions.forEach(function (subscription) {
var requests = subscription.requests;
subscription.callback(doPackage(
requests.filter(matchesSource).map(generateData)
));
});
}
function startGenerating() {
$timeout(function () {
handleSubscriptions();
if (subscriptions.length > 0) {
startGenerating();
}
}, 1000);
}
function subscribe(callback, requests) {
var subscription = {
callback: callback,
requests: requests
};
function unsubscribe() {
subscriptions = subscriptions.filter(function (s) {
return s !== subscription;
});
}
subscriptions.push(subscription);
if (subscriptions.length === 1) {
startGenerating();
}
return unsubscribe;
}
return {
requestTelemetry: requestTelemetry,
subscribe: subscribe
};
}
return ImageTelemetryProvider;
}
);

View File

@@ -1,79 +0,0 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web 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 Web 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([
'../../../platform/features/conductor/core/src/timeSystems/TimeSystem',
'../../../platform/features/conductor/core/src/timeSystems/LocalClock',
'./LADTickSource'
], function (TimeSystem, LocalClock, LADTickSource) {
var THIRTY_MINUTES = 30 * 60 * 1000,
DEFAULT_PERIOD = 1000;
/**
* This time system supports UTC dates and provides a ticking clock source.
* @implements TimeSystem
* @constructor
*/
function LocalTimeSystem ($timeout) {
TimeSystem.call(this);
/**
* Some metadata, which will be used to identify the time system in
* the UI
* @type {{key: string, name: string, glyph: string}}
*/
this.metadata = {
'key': 'local',
'name': 'Local',
'glyph': '\u0043'
};
this.fmts = ['local-format'];
this.sources = [new LocalClock($timeout, DEFAULT_PERIOD), new LADTickSource($timeout, DEFAULT_PERIOD)];
}
LocalTimeSystem.prototype = Object.create(TimeSystem.prototype);
LocalTimeSystem.prototype.formats = function () {
return this.fmts;
};
LocalTimeSystem.prototype.deltaFormat = function () {
return 'duration';
};
LocalTimeSystem.prototype.tickSources = function () {
return this.sources;
};
LocalTimeSystem.prototype.defaults = function (key) {
var now = Math.ceil(Date.now() / 1000) * 1000;
return {
key: 'local-default',
name: 'Local 12 hour time system defaults',
deltas: {start: THIRTY_MINUTES, end: 0},
bounds: {start: now - THIRTY_MINUTES, end: now}
};
};
return LocalTimeSystem;
});

View File

@@ -44,31 +44,31 @@ define(
{
"name": "Min. Air Temperature",
"identifier": "min_temp",
"units": "degrees",
"units": "Degrees (C)",
"type": "float"
},
{
"name": "Max. Air Temperature",
"identifier": "max_temp",
"units": "degrees",
"units": "Degrees (C)",
"type": "float"
},
{
"name": "Atmospheric Pressure",
"identifier": "pressure",
"units": "pascals",
"units": "Millibars",
"type": "float"
},
{
"name": "Min. Ground Temperature",
"identifier": "min_gts_temp",
"units": "degrees",
"units": "Degrees (C)",
"type": "float"
},
{
"name": "Max. Ground Temperature",
"identifier": "max_gts_temp",
"units": "degrees",
"units": "Degrees (C)",
"type": "float"
}
]
@@ -76,4 +76,4 @@ define(
]
};
}
);
);

View File

@@ -48,6 +48,13 @@ define(
this.$http = $http;
this.$log = $log;
this.promise = undefined;
this.dataTransforms = {
//Convert from pascals to millibars
'pressure': function pascalsToMillibars(pascals) {
return pascals / 100;
}
};
}
/**
@@ -65,6 +72,8 @@ define(
var self = this,
id = request.key;
var dataTransforms = this.dataTransforms;
function processResponse(response){
var data = [];
/*
@@ -75,13 +84,14 @@ define(
* Check that valid data exists
*/
if (!isNaN(solData[id])) {
var dataTransform = dataTransforms[id];
/*
* Append each data point to the array of values
* for this data point property (min. temp, etc).
*/
data.unshift({
date: Date.parse(solData[TERRESTRIAL_DATE]),
value: solData[id]
value: dataTransform ? dataTransform(solData[id]) : solData[id]
});
}
});

View File

@@ -16,6 +16,7 @@ define([
{ "key": "styleguide.intro", "name": "Introduction", "cssClass": "icon-page", "description": "Introduction and overview to the style guide" },
{ "key": "styleguide.standards", "name": "Standards", "cssClass": "icon-page", "description": "" },
{ "key": "styleguide.colors", "name": "Colors", "cssClass": "icon-page", "description": "" },
{ "key": "styleguide.status", "name": "status", "cssClass": "icon-page", "description": "Limits, telemetry paused, etc." },
{ "key": "styleguide.glyphs", "name": "Glyphs", "cssClass": "icon-page", "description": "Glyphs overview" },
{ "key": "styleguide.controls", "name": "Controls", "cssClass": "icon-page", "description": "Buttons, selects, HTML controls" },
{ "key": "styleguide.input", "name": "Text Inputs", "cssClass": "icon-page", "description": "Various text inputs" },
@@ -25,6 +26,7 @@ define([
{ "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 },
@@ -47,6 +49,7 @@ define([
"intro",
"standards",
"colors",
"status",
"glyphs",
"styleguide:ui-elements"
]

View File

@@ -28,8 +28,8 @@
color: $colorKey;
}
h1, h2 {
color: pullForward($colorBodyFg, 20%);
h1, h2, strong, b {
color: pullForward($colorBodyFg, 50%);
}
h2 {
@@ -45,6 +45,10 @@
text-transform: uppercase;
}
strong, b {
font-weight: normal;
}
.w-markup {
//Wrap markup example "pre" element
background-color: $colorCode;
@@ -54,6 +58,12 @@
position: relative;
}
.w-mct-example {
div {
margin-bottom: $interiorMarginLg;
}
}
code,
pre {
font-size: 0.8rem;
@@ -143,6 +153,17 @@
// 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;
@@ -155,15 +176,6 @@
margin: $interiorMarginLg 0;
text-align: center;
}
table.details td {
font-size: inherit;
&.label {
color: pushBack($colorBodyFg, 10%);
text-transform: uppercase;
white-space: nowrap;
}
}
}
.item.glyph-item {

View File

@@ -48,7 +48,9 @@
{ 'meaning': 'General usage plus symbol; used in timer object', 'cssClass': 'icon-plus', 'cssContent': 'e926', 'htmlEntity': '&amp;#xe926' },
{ 'meaning': 'Delete', 'cssClass': 'icon-trash', 'cssContent': 'e927', 'htmlEntity': '&amp;#xe927' },
{ 'meaning': 'Close, remove', 'cssClass': 'icon-x', 'cssContent': 'e928', 'htmlEntity': '&amp;#xe928' },
{ 'meaning': 'Enclosing, inclusive; used in Time Conductor', 'cssClass': 'icon-brackets', 'cssContent': 'e929', 'htmlEntity': '&amp;#xe929' }
{ 'meaning': 'Enclosing, inclusive; used in Time Conductor', 'cssClass': 'icon-brackets', 'cssContent': 'e929', 'htmlEntity': '&amp;#xe929' },
{ 'meaning': 'Something is targeted', 'cssClass': 'icon-crosshair', 'cssContent': 'e930', 'htmlEntity': '&amp;#xe930' },
{ 'meaning': 'Draggable', 'cssClass': 'icon-grippy', 'cssContent': 'e931', 'htmlEntity': '&amp;#xe931' }
]; controls= [{ 'meaning': 'Reset zoom/pam', 'cssClass': 'icon-arrows-out', 'cssContent': 'e1000', 'htmlEntity': '&amp;#xe1000' },
{ 'meaning': 'Expand vertically', 'cssClass': 'icon-arrows-right-left', 'cssContent': 'e1001', 'htmlEntity': '&amp;#xe1001' },
{ 'meaning': 'View scrolling', 'cssClass': 'icon-arrows-up-down', 'cssContent': 'e1002', 'htmlEntity': '&amp;#xe1002' },
@@ -84,10 +86,17 @@
{ 'meaning': 'Image thumbs strip; view items grid', 'cssClass': 'icon-thumbs-strip', 'cssContent': 'e1033', 'htmlEntity': '&amp;#xe1033' },
{ 'meaning': 'Two part item, both parts', 'cssClass': 'icon-two-parts-both', 'cssContent': 'e1034', 'htmlEntity': '&amp;#xe1034' },
{ 'meaning': 'Two part item, one only', 'cssClass': 'icon-two-parts-one-only', 'cssContent': 'e1035', 'htmlEntity': '&amp;#xe1035' },
{ 'meaning': 'Resync', 'cssClass': 'icon-resync', 'cssContent': 'e1036', 'htmlEntity': '&amp;#xe1036' },
{ 'meaning': 'Reset', 'cssClass': 'icon-reset', 'cssContent': 'e1037', 'htmlEntity': '&amp;#xe1037' },
{ 'meaning': 'Clear', 'cssClass': 'icon-x-in-circle', 'cssContent': 'e1038', 'htmlEntity': '&amp;#xe1038' },
{ 'meaning': 'Brightness', 'cssClass': 'icon-brightness', 'cssContent': 'e1039', 'htmlEntity': '&amp;#xe1039' },
{ 'meaning': 'Contrast', 'cssClass': 'icon-contrast', 'cssContent': 'e1040', 'htmlEntity': '&amp;#xe1040' },
{ 'meaning': 'Expand', 'cssClass': 'icon-expand', 'cssContent': 'e1041', 'htmlEntity': '&amp;#xe1041' }
{ 'meaning': 'Expand', 'cssClass': 'icon-expand', 'cssContent': 'e1041', 'htmlEntity': '&amp;#xe1041' },
{ 'meaning': 'View items in a tabular list', 'cssClass': 'icon-list-view', 'cssContent': 'e1042', 'htmlEntity': '&amp;#xe1042' },
{ 'meaning': 'Snap an object corner to a grid', 'cssClass': 'icon-grid-snap-to', 'cssContent': 'e1043', 'htmlEntity': '&amp;#xe1043' },
{ 'meaning': 'Do not snap an object corner to a grid', 'cssClass': 'icon-grid-snap-no', 'cssContent': 'e1044', 'htmlEntity': '&amp;#xe1044' },
{ 'meaning': 'Show an object frame in a Display Layout', 'cssClass': 'icon-frame-show', 'cssContent': 'e1045', 'htmlEntity': '&amp;#xe1045' },
{ 'meaning': 'Do not show an object frame in a Display Layout', 'cssClass': 'icon-frame-hide', 'cssContent': 'e1046', 'htmlEntity': '&amp;#xe1046' }
]; objects= [{ 'meaning': 'Activity', 'cssClass': 'icon-activity', 'cssContent': 'e1100', 'htmlEntity': '&amp;#xe1100' },
{ 'meaning': 'Activity Mode', 'cssClass': 'icon-activity-mode', 'cssContent': 'e1101', 'htmlEntity': '&amp;#xe1101' },
{ 'meaning': 'Auto-flow Tabular view', 'cssClass': 'icon-autoflow-tabular', 'cssContent': 'e1102', 'htmlEntity': '&amp;#xe1102' },
@@ -117,7 +126,8 @@
{ 'meaning': 'Timeline object', 'cssClass': 'icon-timeline', 'cssContent': 'e1126', 'htmlEntity': '&amp;#xe1126' },
{ 'meaning': 'Timer object', 'cssClass': 'icon-timer', 'cssContent': 'e1127', 'htmlEntity': '&amp;#xe1127' },
{ 'meaning': 'Data Topic', 'cssClass': 'icon-topic', 'cssContent': 'e1128', 'htmlEntity': '&amp;#xe1128' },
{ 'meaning': 'Fixed Position object', 'cssClass': 'icon-box-with-dashed-lines', 'cssContent': 'e1129', 'htmlEntity': '&amp;#xe1129' }
{ 'meaning': 'Fixed Position object', 'cssClass': 'icon-box-with-dashed-lines', 'cssContent': 'e1129', 'htmlEntity': '&amp;#xe1129' },
{ 'meaning': 'Summary Widget', 'cssClass': 'icon-summary-widget', 'cssContent': 'e1130', 'htmlEntity': '&amp;#xe1130' }
];
"></div>
@@ -141,8 +151,8 @@
<h2>How to Use Glyphs</h2>
<div class="cols cols1-1">
<div class="col">
<p>The easiest way to use a glyph is to include its CSS class in element. The CSS adds a psuedo <code>:before</code> HTML element to whatever element it's attached to that makes proper use of the symbols font.</p>
<p>Alternately, you can use the <code>.ui-symbol</code> class in an object that contains encoded HTML entities. This method is only recommended if you cannot use the aforementioned CSS class approach for some reason.</p>
<p>The easiest way to use a glyph is to include its CSS class in an element. The CSS adds a psuedo <code>:before</code> HTML element to whatever element it's attached to that makes proper use of the symbols font.</p>
<p>Alternately, you can use the <code>.ui-symbol</code> class in an object that contains encoded HTML entities. This method is only recommended if you cannot use the aforementioned CSS class approach.</p>
</div>
<mct-example><a class="s-button icon-gear" title="Settings"></a>
<br /><br />
@@ -160,8 +170,8 @@
<div class="item glyph-item" ng-repeat="glyph in general">
<div class="glyph" ng-class="glyph.cssClass"></div>
<table class="details">
<tr><td class="label">Meaning</td><td class="value">{{glyph.meaning}}</td></tr>
<tr><td class="label">Class</td><td class="value">.{{glyph.cssClass}}</td></tr>
<tr><td class="label">Meaning</td><td class="value">{{glyph.meaning}}</td></tr>
<tr><td class="label">CSS Content</td><td class="value">\{{glyph.cssContent}}</td></tr>
<tr><td class="label">HTML Entity</td><td class="value">{{glyph.htmlEntity}}</td></tr>
</table>
@@ -176,8 +186,8 @@
<div class="item glyph-item" ng-repeat="glyph in controls">
<div class="glyph" ng-class="glyph.cssClass"></div>
<table class="details">
<tr><td class="label">Meaning</td><td class="value">{{glyph.meaning}}</td></tr>
<tr><td class="label">Class</td><td class="value">.{{glyph.cssClass}}</td></tr>
<tr><td class="label">Meaning</td><td class="value">{{glyph.meaning}}</td></tr>
<tr><td class="label">CSS Content</td><td class="value">\{{glyph.cssContent}}</td></tr>
<tr><td class="label">HTML Entity</td><td class="value">{{glyph.htmlEntity}}</td></tr>
</table>
@@ -192,8 +202,8 @@
<div class="item glyph-item" ng-repeat="glyph in objects">
<div class="glyph" ng-class="glyph.cssClass"></div>
<table class="details">
<tr><td class="label">Meaning</td><td class="value">{{glyph.meaning}}</td></tr>
<tr><td class="label">Class</td><td class="value">.{{glyph.cssClass}}</td></tr>
<tr><td class="label">Meaning</td><td class="value">{{glyph.meaning}}</td></tr>
<tr><td class="label">CSS Content</td><td class="value">\{{glyph.cssContent}}</td></tr>
<tr><td class="label">HTML Entity</td><td class="value">{{glyph.htmlEntity}}</td></tr>
</table>

View File

@@ -4,5 +4,5 @@
<pre></pre>
</span>
<h3>Example</h3>
<div></div>
<div class="w-mct-example"></div>
</div>

View File

@@ -0,0 +1,142 @@
<!--
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.
-->
<style>
.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: 4px;
padding: 3px 7px;
}
.w-mct-example table {
width: 100%;
}
</style>
<div class="l-style-guide s-text">
<p class="doc-title">Open MCT Style Guide</p>
<h1>Status Indication</h1>
<div class="l-section">
<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>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>
<li><code>s-status-warning-hi</code></li>
<li><code>s-status-warning-lo</code></li>
<li><code>s-status-diagnostic</code></li>
<li><code>s-status-info</code></li>
<li><code>s-status-ok</code></li>
</ul>
<li>Color and icon</li>
<ul>
<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><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>
<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>Synchronization</h2>
<div class="cols cols1-1">
<div class="col">
<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><div class="s-unsynced">This element is unsynced</div>
</mct-example>
</div>
</div>
</div>

View File

@@ -34,6 +34,7 @@ define(
pages['standards'] = { name: "Standards", type: "styleguide.standards", location: "styleguide:home" };
pages['colors'] = { name: "Colors", type: "styleguide.colors", location: "styleguide:home" };
pages['glyphs'] = { name: "Glyphs", type: "styleguide.glyphs", location: "styleguide:home" };
pages['status'] = { name: "Status Indication", type: "styleguide.status", location: "styleguide:home" };
pages['controls'] = { name: "Controls", type: "styleguide.controls", location: "styleguide:ui-elements" };
pages['input'] = { name: "Text Inputs", type: "styleguide.input", location: "styleguide:ui-elements" };
pages['menus'] = { name: "Menus", type: "styleguide.menus", location: "styleguide:ui-elements" };

View File

@@ -77,11 +77,15 @@ if (process.env.NODE_ENV === 'development') {
gulp.task('scripts', function () {
var requirejsOptimize = require('gulp-requirejs-optimize');
var replace = require('gulp-replace-task');
var header = require('gulp-header');
var comment = fs.readFileSync('src/about.frag');
return gulp.src(paths.main)
.pipe(sourcemaps.init())
.pipe(requirejsOptimize(options.requirejsOptimize))
.pipe(sourcemaps.write('.'))
.pipe(replace(options.replace))
.pipe(header(comment, options.replace.variables))
.pipe(gulp.dest(paths.dist));
});

View File

@@ -28,9 +28,10 @@
<script src="bower_components/requirejs/require.js">
</script>
<script>
var THIRTY_MINUTES = 30 * 60 * 1000;
require(['openmct'], function (openmct) {
[
'example/imagery',
'example/eventGenerator',
'example/styleguide'
].forEach(
@@ -40,7 +41,32 @@
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.Conductor({
menuOptions: [
{
name: "Fixed",
timeSystem: 'utc',
bounds: {
start: Date.now() - 30 * 60 * 1000,
end: Date.now()
}
},
{
name: "Realtime",
timeSystem: 'utc',
clock: 'local',
clockOffsets: {
start: -25 * 60 * 1000,
end: 5 * 60 * 1000
}
}
]
}));
openmct.time.clock('local', {start: -THIRTY_MINUTES, end: 0});
openmct.time.timeSystem('utc');
openmct.start();
});
</script>

View File

@@ -37,6 +37,7 @@ module.exports = function(config) {
{pattern: 'bower_components/**/*.js', included: false},
{pattern: 'node_modules/d3-*/**/*.js', included: false},
{pattern: 'src/**/*.js', included: false},
{pattern: 'example/**/*.html', included: false},
{pattern: 'example/**/*.js', included: false},
{pattern: 'example/**/*.json', included: false},
{pattern: 'platform/**/*.js', included: false},

View File

@@ -32,6 +32,7 @@ requirejs.config({
"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/FileSaver.js/FileSaver.min",
"screenfull": "bower_components/screenfull/dist/screenfull.min",
"text": "bower_components/text/text",
@@ -100,11 +101,5 @@ define([
return new Main().run(defaultRegistry);
});
// For now, install conductor by default
openmct.install(openmct.plugins.Conductor({
showConductor: false
}));
return openmct;
});

View File

@@ -21,7 +21,8 @@
"bower": "^1.7.7",
"git-rev-sync": "^1.4.0",
"glob": ">= 3.0.0",
"gulp": "^3.9.0",
"gulp": "^3.9.1",
"gulp-header": "^1.8.8",
"gulp-jscs": "^3.0.2",
"gulp-jshint": "^2.0.0",
"gulp-jshint-html-reporter": "^0.1.3",

View File

@@ -107,7 +107,9 @@ define([
"depends": [
"$scope",
"agentService",
"$window"
"$window",
"$location",
"$attrs"
]
},
{
@@ -134,7 +136,9 @@ define([
"$scope",
"agentService",
"$window",
"navigationService"
"navigationService",
"$location",
"$attrs"
]
}
],
@@ -240,7 +244,7 @@ define([
"views": [
{
"key": "items",
"name": "Items",
"name": "Grid",
"cssClass": "icon-thumbs-strip",
"description": "Grid of available items",
"template": itemsTemplate,

View File

@@ -20,7 +20,7 @@
at runtime from the About dialog for additional information.
-->
<div ng-controller="BrowseObjectController" class="abs l-flex-col">
<div class="holder flex-elem l-flex-row object-browse-bar ">
<div class="holder flex-elem l-flex-row object-browse-bar t-primary">
<div class="items-select left flex-elem l-flex-row grows">
<mct-representation key="'back-arrow'"
mct-object="domainObject"
@@ -31,16 +31,18 @@
</mct-representation>
</div>
<div class="btn-bar right l-flex-row flex-elem flex-justify-end flex-fixed">
<mct-representation key="'switcher'"
mct-object="domainObject"
ng-model="representation">
</mct-representation>
<!-- Temporarily, on mobile, the action buttons are hidden-->
<mct-representation key="'action-group'"
mct-object="domainObject"
parameters="{ category: 'view-control' }"
class="mobile-hide">
</mct-representation>
<span class="l-object-action-buttons">
<mct-representation key="'switcher'"
mct-object="domainObject"
ng-model="representation">
</mct-representation>
<!-- Temporarily, on mobile, the action buttons are hidden-->
<mct-representation key="'action-group'"
mct-object="domainObject"
parameters="{ category: 'view-control' }"
class="mobile-hide l-object-action-buttons">
</mct-representation>
</span>
</div>
</div>
<div class="holder l-flex-col flex-elem grows l-object-wrapper l-controls-visible l-time-controller-visible">

View File

@@ -24,9 +24,9 @@
<mct-include key="'topbar-browse'"></mct-include>
<div class="abs holder holder-main browse-area s-browse-area browse-wrapper"
ng-controller="PaneController as modelPaneTree"
ng-class="modelPaneTree.visible() ? 'pane-tree-showing' : 'pane-tree-hidden'">
ng-class="modelPaneTree.visible() ? 'pane-tree-showing' : 'pane-tree-hidden'" hide-parameter="hideTree">
<mct-split-pane class='abs contents'
anchor='left'>
anchor='left' alias="leftSide">
<div class='split-pane-component treeview pane left'>
<div class="abs holder l-flex-col holder-treeview-elements">
<mct-representation key="'create-button'"
@@ -58,9 +58,10 @@
<div class='holder holder-object-and-inspector abs' id='content-area'
ng-controller="InspectorPaneController as modelPaneInspect"
ng-class="modelPaneInspect.visible() ? 'pane-inspect-showing' : 'pane-inspect-hidden'">
ng-class="modelPaneInspect.visible() ? 'pane-inspect-showing' : 'pane-inspect-hidden'"
hide-parameter="hideInspector">
<mct-split-pane class='l-object-and-inspector contents abs' anchor='right'>
<mct-split-pane class='l-object-and-inspector contents abs' anchor='right' alias="rightSide">
<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'"
@@ -87,4 +88,3 @@
</div>
<mct-include key="'bottombar'"></mct-include>
</div>

View File

@@ -28,4 +28,4 @@
key="'menu-arrow'"
mct-object='domainObject'
class="flex-elem context-available-w"></mct-representation>
</span>
</span>

View File

@@ -25,8 +25,8 @@
* @namespace platform/commonUI/browse
*/
define(
[],
function () {
['lodash'],
function (_) {
/**
* The BrowseController is used to populate the initial scope in Browse
@@ -113,11 +113,22 @@ define(
$location.path('/browse/' + currentIds);
}
function getLastChildIfRoot(object) {
if (object.getId() !== 'ROOT') {
return object;
}
return object.useCapability('composition')
.then(function (composees) {
return composees[composees.length - 1];
});
}
function navigateToPath(path) {
return getObject('ROOT')
.then(function (root) {
return findViaComposition(root, path);
})
.then(getLastChildIfRoot)
.then(function (object) {
navigationService.setNavigation(object);
});
@@ -146,11 +157,31 @@ define(
// (e.g. bookmarks to pages in OpenMCT) and prevent them. Instead,
// navigate to the path ourselves, which results in it being
// properly set.
$scope.$on('$routeChangeStart', function (event, route) {
if (route.$$route === $route.current.$$route &&
route.pathParams.ids !== $route.current.pathParams.ids) {
event.preventDefault();
navigateToPath(route.pathParams.ids.split('/'));
$scope.$on('$routeChangeStart', function (event, route, oldRoute) {
if (route.$$route === $route.current.$$route) {
if (route.pathParams.ids &&
route.pathParams.ids !== $route.current.pathParams.ids) {
var otherParams = _.omit(route.params, 'ids');
var oldOtherParams = _.omit(oldRoute.params, 'ids');
var deletedParams = _.omit(oldOtherParams, _.keys(otherParams));
event.preventDefault();
navigateToPath(route.pathParams.ids.split('/'))
.then(function () {
if (!_.isEqual(otherParams, oldOtherParams)) {
_.forEach(otherParams, function (v, k) {
$location.search(k, v);
});
_.forEach(deletedParams, function (k) {
$location.search(k, null);
});
}
});
} else {
navigateToPath([]);
}
}
});

View File

@@ -35,9 +35,8 @@ define(
* @param navigationService
* @constructor
*/
function InspectorPaneController($scope, agentService, $window, navigationService) {
PaneController.call(this, $scope, agentService, $window);
function InspectorPaneController($scope, agentService, $window, navigationService, $location, $attrs) {
PaneController.call(this, $scope, agentService, $window, $location, $attrs);
var statusListener,
self = this;

View File

@@ -31,12 +31,17 @@ define(
* @constructor
* @memberof platform/commonUI/browse
*/
function PaneController($scope, agentService, $window) {
function PaneController($scope, agentService, $window, $location, $attrs) {
var self = this;
this.agentService = agentService;
var hideParameterPresent = $location.search().hasOwnProperty($attrs.hideParameter);
// Fast and cheap: if this has been opened in a new window, hide panes by default
this.state = !$window.opener;
if ($attrs.hideParameter && hideParameterPresent) {
this.state = false;
$location.search($attrs.hideParameter, undefined);
} else {
this.state = true;
}
/**
* Callback to invoke when any selection occurs in the tree.
@@ -70,7 +75,7 @@ define(
* @returns {boolean} true when visible
*/
PaneController.prototype.visible = function () {
return this.state;
return !!this.state;
};
return PaneController;

View File

@@ -38,6 +38,7 @@ define(
this.urlService = urlService;
this.open = function () {
arguments[0] += "&hideTree=true&hideInspector=true";
$window.open.apply($window, arguments);
};

View File

@@ -33,7 +33,9 @@ define(
mockNavigationService,
mockNavigationUnlistener,
mockStatusUnlistener,
controller;
controller,
mockLocation,
mockAttrs;
beforeEach(function () {
mockScope = jasmine.createSpyObj("$scope", ["$on"]);
@@ -71,7 +73,12 @@ define(
mockDomainObject.hasCapability.andReturn(true);
mockDomainObject.getCapability.andReturn(mockStatusCapability);
controller = new InspectorPaneController(mockScope, mockAgentService, mockWindow, mockNavigationService);
mockLocation = jasmine.createSpyObj('location', ['search']);
mockLocation.search.andReturn({});
mockAttrs = {};
controller = new InspectorPaneController(mockScope, mockAgentService, mockWindow, mockNavigationService, mockLocation, mockAttrs);
});
it("listens for changes to navigation and attaches a status" +

View File

@@ -29,7 +29,9 @@ define(
mockAgentService,
mockDomainObjects,
mockWindow,
controller;
controller,
mockLocation,
mockAttrs;
// We want to reinstantiate for each test case
// because device state can influence constructor-time behavior
@@ -37,7 +39,9 @@ define(
return new PaneController(
mockScope,
mockAgentService,
mockWindow
mockWindow,
mockLocation,
mockAttrs
);
}
@@ -59,6 +63,11 @@ define(
["isMobile", "isPhone", "isTablet", "isPortrait", "isLandscape"]
);
mockWindow = jasmine.createSpyObj("$window", ["open"]);
mockLocation = jasmine.createSpyObj('location', ['search']);
mockLocation.search.andReturn({});
mockAttrs = {};
});
it("is initially visible", function () {
@@ -86,6 +95,24 @@ define(
// Tree should have collapsed
expect(controller.visible()).toBeFalsy();
});
describe("specifying hideParameter", function () {
beforeEach(function () {
mockAttrs = {hideParameter: 'hideTree'};
});
it("sets pane state to false when in location.search", function () {
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.andReturn({});
expect(instantiateController().visible()).toBe(true);
expect(mockLocation.search).not.toHaveBeenCalledWith('hideTree', undefined);
});
});
});
}
);

View File

@@ -16,7 +16,7 @@
</div>
<div class="bottom-bar">
<a ng-repeat="dialogOption in ngModel.options"
class="s-button major"
class="s-button"
ng-click="dialogOption.callback()">
{{dialogOption.label}}
</a>

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="abs overlay" ng-class="{'delayEntry100ms' : ngModel.delay}">
<div class="abs overlay l-dialog" ng-class="{'delayEntry100ms' : ngModel.delay}">
<div class="abs blocker"></div>
<div class="abs holder">
<div class="abs outer-holder">
<a ng-click="ngModel.cancel()"
ng-if="ngModel.cancel"
class="close icon-x"></a>
<div class="abs contents" ng-transclude></div>
class="close icon-x-in-circle"></a>
<div class="abs inner-holder contents" ng-transclude></div>
</div>
</div>

View File

@@ -33,8 +33,8 @@ define([
) {
legacyRegistry.register("platform/commonUI/formats", {
"name": "Time services bundle",
"description": "Defines interfaces and provides default implementations for handling different time systems.",
"name": "Format Registry",
"description": "Provides a registry for formats, which allow parsing and formatting of values.",
"extensions": {
"components": [
{

View File

@@ -44,6 +44,7 @@ define([
* @memberof platform/commonUI/formats
*/
function DurationFormat() {
this.key = "duration";
}
DurationFormat.prototype.format = function (value) {

View File

@@ -30,19 +30,23 @@ define([
* An object used to convert between numeric values and text values,
* typically used to display these values to the user and to convert
* user input to a numeric format, particularly for time formats.
* @interface {Format}
* @interface Format
*/
/**
* Parse text (typically user input) to a numeric value.
* Behavior is undefined when the text cannot be parsed;
* `validate` should be called first if the text may be invalid.
* @method parse
* @method Format#parse
* @memberof Format#
* @param {string} text the text to parse
* @returns {number} the parsed numeric value
*/
/**
* @property {string} key A unique identifier for this formatter.
* @memberof Format#
*/
/**
* Determine whether or not some text (typically user input) can
* be parsed to a numeric value by this format.
@@ -58,10 +62,12 @@ define([
* @method format
* @memberof Format#
* @param {number} value the numeric value to format
* @param {number} [threshold] Optionally provides context to the
* format request, allowing for scale-appropriate formatting. This value
* should be the minimum unit to be represented by this format, in ms. For
* example, to display seconds, a threshold of 1 * 1000 should be provided.
* @param {number} [minValue] Contextual information for scaled formatting used in linear scales such as conductor
* and plot axes. Specifies the smallest number on the scale.
* @param {number} [maxValue] Contextual information for scaled formatting used in linear scales such as conductor
* and plot axes. Specifies the largest number on the scale
* @param {number} [count] Contextual information for scaled formatting used in linear scales such as conductor
* and plot axes. The number of labels on the scale.
* @returns {string} the text representation of the value
*/

View File

@@ -1,5 +1,5 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* Open MCT, Copyright (c) 2014-2016, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
@@ -49,6 +49,7 @@ define([
* @memberof platform/commonUI/formats
*/
function UTCTimeFormat() {
this.key = "utc";
}
/**
@@ -64,7 +65,7 @@ define([
*
* Licensed
*/
return [
var format = [
[".SSS", function (m) {
return m.milliseconds();
}],
@@ -91,64 +92,32 @@ define([
return true;
}]
].filter(function (row) {
return row[1](momentified);
})[0][0];
return row[1](momentified);
})[0][0];
if (format !== undefined) {
return moment.utc(d).format(format);
}
}
/**
* Returns a description of the current range of the time conductor's
* bounds.
* @param timeRange
* @returns {*}
* @param {number} value The value to format.
* @param {number} [minValue] Contextual information for scaled formatting used in linear scales such as conductor
* and plot axes. Specifies the smallest number on the scale.
* @param {number} [maxValue] Contextual information for scaled formatting used in linear scales such as conductor
* and plot axes. Specifies the largest number on the scale
* @param {number} [count] Contextual information for scaled formatting used in linear scales such as conductor
* and plot axes. The number of labels on the scale.
* @returns {string} the formatted date(s). If multiple values were requested, then an array of
* formatted values will be returned. Where a value could not be formatted, `undefined` will be returned at its position
* in the array.
*/
UTCTimeFormat.prototype.timeUnits = function (timeRange) {
var momentified = moment.duration(timeRange);
return [
["Decades", function (r) {
return r.years() > 15;
}],
["Years", function (r) {
return r.years() > 1;
}],
["Months", function (r) {
return r.years() === 1 || r.months() > 1;
}],
["Days", function (r) {
return r.months() === 1 || r.days() > 1;
}],
["Hours", function (r) {
return r.days() === 1 || r.hours() > 1;
}],
["Minutes", function (r) {
return r.hours() === 1 || r.minutes() > 1;
}],
["Seconds", function (r) {
return r.minutes() === 1 || r.seconds() > 1;
}],
["Milliseconds", function (r) {
return true;
}]
].filter(function (row) {
return row[1](momentified);
})[0][0];
};
/**
*
* @param value
* @param {Scale} [scale] Optionally provides context to the
* format request, allowing for scale-appropriate formatting.
* @returns {string} the formatted date
*/
UTCTimeFormat.prototype.format = function (value, scale) {
if (scale !== undefined) {
var scaledFormat = getScaledFormat(value, scale);
if (scaledFormat) {
return moment.utc(value).format(scaledFormat);
}
UTCTimeFormat.prototype.format = function (value) {
if (arguments.length > 1) {
return getScaledFormat(value);
} else {
return moment.utc(value).format(DATE_FORMAT) + "Z";
}
return moment.utc(value).format(DATE_FORMAT) + "Z";
};
UTCTimeFormat.prototype.parse = function (text) {

View File

@@ -1,83 +0,0 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web 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 Web 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([
"./UTCTimeFormat",
"moment"
], function (
UTCTimeFormat,
moment
) {
describe("The UTCTimeFormat class", function () {
var format;
var scale;
beforeEach(function () {
format = new UTCTimeFormat();
scale = {min: 0, max: 0};
});
it("Provides an appropriately scaled time format based on the input" +
" time", function () {
var TWO_HUNDRED_MS = 200;
var THREE_SECONDS = 3000;
var FIVE_MINUTES = 5 * 60 * 1000;
var ONE_HOUR_TWENTY_MINS = (1 * 60 * 60 * 1000) + (20 * 60 * 1000);
var TEN_HOURS = (10 * 60 * 60 * 1000);
var JUNE_THIRD = moment.utc("2016-06-03", "YYYY-MM-DD");
var APRIL = moment.utc("2016-04", "YYYY-MM");
var TWENTY_SIXTEEN = moment.utc("2016", "YYYY");
expect(format.format(TWO_HUNDRED_MS, scale)).toBe(".200");
expect(format.format(THREE_SECONDS, scale)).toBe(":03");
expect(format.format(FIVE_MINUTES, scale)).toBe("00:05");
expect(format.format(ONE_HOUR_TWENTY_MINS, scale)).toBe("01:20");
expect(format.format(TEN_HOURS, scale)).toBe("10");
expect(format.format(JUNE_THIRD, scale)).toBe("Fri 03");
expect(format.format(APRIL, scale)).toBe("April");
expect(format.format(TWENTY_SIXTEEN, scale)).toBe("2016");
});
it("Returns appropriate time units for a given time span", function () {
var ONE_DAY = 1000 * 60 * 60 * 24;
var FIVE_DAYS = 5 * ONE_DAY;
var FIVE_MONTHS = 60 * ONE_DAY;
var ONE_YEAR = 365 * ONE_DAY;
var SEVEN_YEARS = 7 * ONE_YEAR;
var TWO_DECADES = 20 * ONE_YEAR;
//A span of one day should show a zoom label of "Hours"
expect(format.timeUnits(ONE_DAY)).toEqual("Hours");
//Multiple days should display "Days"
expect(format.timeUnits(FIVE_DAYS)).toEqual("Days");
expect(format.timeUnits(FIVE_MONTHS)).toEqual("Days");
//A span of one year should show a zoom level of "Months".
// Multiple years will show "Years"
expect(format.timeUnits(ONE_YEAR)).toEqual("Months");
expect(format.timeUnits(SEVEN_YEARS)).toEqual("Years");
expect(format.timeUnits(TWO_DECADES)).toEqual("Decades");
});
});
});

View File

@@ -1,9 +1,9 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* Open MCT Web, 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
* Open MCT Web 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.
@@ -14,47 +14,49 @@
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define(
['../src/UTCTimeFormat', 'moment'],
function (UTCTimeFormat, moment) {
define([
"../src/UTCTimeFormat",
"moment"
], function (
UTCTimeFormat,
moment
) {
describe("The UTCTimeFormat class", function () {
var format;
var scale;
describe("The UTCTimeFormat", function () {
var format;
beforeEach(function () {
format = new UTCTimeFormat();
});
it("formats UTC timestamps", function () {
var timestamp = 12345670000,
formatted = format.format(timestamp);
expect(formatted).toEqual(jasmine.any(String));
expect(moment.utc(formatted).valueOf()).toEqual(timestamp);
});
it("displays with millisecond precision", function () {
var timestamp = 12345670789,
formatted = format.format(timestamp);
expect(moment.utc(formatted).valueOf()).toEqual(timestamp);
});
it("validates time inputs", function () {
expect(format.validate("1977-05-25 11:21:22")).toBe(true);
expect(format.validate("garbage text")).toBe(false);
});
it("parses valid input", function () {
var text = "1977-05-25 11:21:22",
parsed = format.parse(text);
expect(parsed).toEqual(jasmine.any(Number));
expect(parsed).toEqual(moment.utc(text).valueOf());
});
beforeEach(function () {
format = new UTCTimeFormat();
scale = {min: 0, max: 0};
});
}
);
it("Provides an appropriately scaled time format based on the input" +
" time", function () {
var TWO_HUNDRED_MS = 200;
var THREE_SECONDS = 3000;
var FIVE_MINUTES = 5 * 60 * 1000;
var ONE_HOUR_TWENTY_MINS = (1 * 60 * 60 * 1000) + (20 * 60 * 1000);
var TEN_HOURS = (10 * 60 * 60 * 1000);
var JUNE_THIRD = moment.utc("2016-06-03", "YYYY-MM-DD");
var APRIL = moment.utc("2016-04", "YYYY-MM");
var TWENTY_SIXTEEN = moment.utc("2016", "YYYY");
expect(format.format(TWO_HUNDRED_MS, scale)).toBe(".200");
expect(format.format(THREE_SECONDS, scale)).toBe(":03");
expect(format.format(FIVE_MINUTES, scale)).toBe("00:05");
expect(format.format(ONE_HOUR_TWENTY_MINS, scale)).toBe("01:20");
expect(format.format(TEN_HOURS, scale)).toBe("10");
expect(format.format(JUNE_THIRD, scale)).toBe("Fri 03");
expect(format.format(APRIL, scale)).toBe("April");
expect(format.format(TWENTY_SIXTEEN, scale)).toBe("2016");
});
});
});

View File

@@ -374,7 +374,8 @@ define([
"depends": [
"$parse",
"$log",
"$interval"
"$interval",
"$window"
]
},
{

View File

@@ -1,207 +1,144 @@
{
"metadata": {
"name": "openmct-symbols-12px",
"lastOpened": 1467322505818,
"created": 1467322503679
},
"iconSets": [
{
"selection": [
{
"order": 4,
"id": 2,
"prevSize": 12,
"code": 59671,
"name": "icon12-eye-open",
"tempChar": ""
},
{
"order": 7,
"id": 5,
"prevSize": 12,
"code": 921607,
"name": "icon12-pane-collapse-left",
"tempChar": ""
},
{
"order": 8,
"id": 4,
"prevSize": 12,
"code": 921608,
"name": "icon12-pane-collapse-right",
"tempChar": ""
},
{
"order": 6,
"id": 3,
"prevSize": 12,
"code": 921865,
"name": "icon12-folder",
"tempChar": ""
}
],
"id": 0,
"metadata": {
"name": "openmct-symbols-12px",
"importSize": {
"width": 320,
"height": 384
},
"designer": "Charles Hacskaylo"
},
"height": 1024,
"prevSize": 12,
"icons": [
{
"id": 2,
"paths": [
"M512 86c-257.92 0-471.28 185.147-506.667 426 35.493 240.853 248.853 426 506.667 426s471.28-185.147 506.667-426c-35.387-240.853-248.747-426-506.667-426zM738.373 685.2c-131.048 109.517-321.699 109.517-452.747 0-53.328-44.749-90.832-105.477-106.96-173.2 16.101-67.707 53.565-128.435 106.853-173.2 131.048-109.517 321.699-109.517 452.747 0 53.368 44.733 90.909 105.464 107.067 173.2-16.128 67.723-53.632 128.451-106.96 173.2z",
"M682.667 512c0 94.257-76.41 170.667-170.667 170.667s-170.667-76.41-170.667-170.667c0-94.257 76.41-170.667 170.667-170.667s170.667 76.41 170.667 170.667z"
],
"attrs": [],
"isMulticolor": false,
"grid": 0,
"tags": [
"icon12-eye-open"
],
"colorPermutations": {
"1161751": [
{
"f": 0
},
{
"f": 0
}
]
}
},
{
"id": 5,
"paths": [
"M0 0h170.667v1024h-170.667v-1024z",
"M853.333 256h-256v-256l-341.333 426.667 341.333 426.667v-256h256v-341.333z"
],
"attrs": [
{
"opacity": 1
},
{
"opacity": 1
}
],
"isMulticolor": false,
"width": 853,
"grid": 0,
"tags": [
"icon12-pane-collapse-left"
],
"colorPermutations": {
"1161751": [
{},
{}
]
}
},
{
"id": 4,
"paths": [
"M682.667 0h170.667v1024h-170.667v-1024z",
"M0 256h256v-256l341.333 426.667-341.333 426.667v-256h-256v-341.333z"
],
"attrs": [
{
"opacity": 1
},
{
"opacity": 1
}
],
"isMulticolor": false,
"width": 853,
"grid": 0,
"tags": [
"icon12-pane-collapse-right"
],
"colorPermutations": {
"1161751": [
{},
{}
]
}
},
{
"id": 3,
"paths": [
"M938.667 170.667h-341.333l-110.32-110.32c-33.2-33.2-98.667-60.347-145.68-60.347h-256c-47.073 0.136-85.197 38.26-85.333 85.32l-0 341.346c0.136-47.073 38.26-85.197 85.32-85.333l853.346-0c47.073 0.136 85.197 38.26 85.333 85.32l0-170.654c-0.136-47.073-38.26-85.197-85.32-85.333z",
"M85.333 426.667h853.333c47.128 0 85.333 38.205 85.333 85.333v426.667c0 47.128-38.205 85.333-85.333 85.333h-853.333c-47.128 0-85.333-38.205-85.333-85.333v-426.667c0-47.128 38.205-85.333 85.333-85.333z"
],
"attrs": [],
"isMulticolor": false,
"grid": 0,
"tags": [
"icon12-folder"
],
"colorPermutations": {
"1161751": [
{
"f": 0
},
{
"f": 0
}
]
}
}
],
"invisible": false,
"colorThemes": [
[
[
0,
0,
0,
1
],
[
0,
161,
75,
1
]
]
],
"colorThemeIdx": 0
}
],
"preferences": {
"showGlyphs": true,
"showCodes": true,
"showQuickUse": true,
"showQuickUse2": true,
"showSVGs": true,
"fontPref": {
"prefix": "icon-",
"metadata": {
"fontFamily": "openmct-symbols-12px",
"majorVersion": 1,
"minorVersion": 0
},
"metrics": {
"emSize": 1024,
"baseline": 6.25,
"whitespace": 50
},
"embed": false
},
"imagePref": {
"prefix": "icon-",
"png": true,
"useClassSelector": true,
"color": 0,
"bgColor": 16777215
},
"historySize": 100,
"gridSize": 16
},
"uid": -1
}
"metadata": {
"name": "openmct-symbols-12px",
"lastOpened": 0,
"created": 1502213994889
},
"iconSets": [
{
"selection": [
{
"order": 9,
"id": 6,
"name": "icon12-crosshair",
"prevSize": 12,
"code": 59696,
"tempChar": ""
},
{
"order": 6,
"id": 3,
"prevSize": 12,
"code": 921865,
"name": "icon12-folder",
"tempChar": ""
}
],
"id": 0,
"metadata": {
"name": "openmct-symbols-12px",
"importSize": {
"width": 384,
"height": 384
},
"designer": "Charles Hacskaylo"
},
"height": 1024,
"prevSize": 12,
"icons": [
{
"id": 6,
"paths": [
"M597.333 0h-170.667v256h170.667v-256z",
"M1024 426.667h-256v170.667h256v-170.667z",
"M597.333 768h-170.667v256h170.667v-256z",
"M256 426.667h-256v170.667h256v-170.667z"
],
"attrs": [
{},
{},
{},
{}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 0,
"tags": [
"icon12-crosshair"
],
"colorPermutations": {
"1161751": [
{},
{},
{},
{}
]
}
},
{
"id": 3,
"paths": [
"M938.667 170.667h-341.333l-110.32-110.32c-33.2-33.2-98.667-60.347-145.68-60.347h-256c-47.073 0.136-85.197 38.26-85.333 85.32l-0 341.346c0.136-47.073 38.26-85.197 85.32-85.333l853.346-0c47.073 0.136 85.197 38.26 85.333 85.32l0-170.654c-0.136-47.073-38.26-85.197-85.32-85.333z",
"M85.333 426.667h853.333c47.128 0 85.333 38.205 85.333 85.333v426.667c0 47.128-38.205 85.333-85.333 85.333h-853.333c-47.128 0-85.333-38.205-85.333-85.333v-426.667c0-47.128 38.205-85.333 85.333-85.333z"
],
"attrs": [],
"isMulticolor": false,
"grid": 0,
"tags": [
"icon12-folder"
],
"colorPermutations": {
"1161751": [
{
"f": 0
},
{
"f": 0
}
]
}
}
],
"invisible": false,
"colorThemes": [
[
[
0,
0,
0,
1
],
[
0,
161,
75,
1
]
]
],
"colorThemeIdx": 0
}
],
"preferences": {
"showGlyphs": true,
"showCodes": true,
"showQuickUse": true,
"showQuickUse2": true,
"showSVGs": true,
"fontPref": {
"prefix": "icon-",
"metadata": {
"fontFamily": "openmct-symbols-12px",
"majorVersion": 1,
"minorVersion": 0
},
"metrics": {
"emSize": 1024,
"baseline": 6.25,
"whitespace": 50
},
"embed": false
},
"imagePref": {
"prefix": "icon-",
"png": true,
"useClassSelector": true,
"color": 0,
"bgColor": 16777215
},
"historySize": 100,
"gridSize": 16
},
"uid": -1,
"time": 1502216581486
}

View File

@@ -7,8 +7,6 @@
<font-face units-per-em="1024" ascent="960" descent="-64" />
<missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" horiz-adv-x="512" d="" />
<glyph unicode="&#xe917;" glyph-name="icon12-eye-open" d="M512 852.667c-257.92 0-471.28-185.147-506.667-426 35.493-240.853 248.853-426 506.667-426s471.28 185.147 506.667 426c-35.387 240.853-248.747 426-506.667 426zM738.373 253.467c-131.048-109.517-321.699-109.517-452.747 0-53.328 44.749-90.832 105.477-106.96 173.2 16.101 67.707 53.565 128.435 106.853 173.2 131.048 109.517 321.699 109.517 452.747 0 53.368-44.733 90.909-105.464 107.067-173.2-16.128-67.723-53.632-128.451-106.96-173.2zM682.667 426.667c0-94.257-76.41-170.667-170.667-170.667s-170.667 76.41-170.667 170.667c0 94.257 76.41 170.667 170.667 170.667s170.667-76.41 170.667-170.667z" />
<glyph unicode="&#xe1007;" glyph-name="icon12-pane-collapse-left" horiz-adv-x="853" d="M0 938.667h170.667v-1024h-170.667v1024zM853.333 682.667h-256v256l-341.333-426.667 341.333-426.667v256h256v341.333z" />
<glyph unicode="&#xe1008;" glyph-name="icon12-pane-collapse-right" horiz-adv-x="853" d="M682.667 938.667h170.667v-1024h-170.667v1024zM0 682.667h256v256l341.333-426.667-341.333-426.667v256h-256v341.333z" />
<glyph unicode="&#xe930;" glyph-name="icon12-crosshair" d="M597.333 938.667h-170.667v-256h170.667v256zM1024 512h-256v-170.667h256v170.667zM597.333 170.667h-170.667v-256h170.667v256zM256 512h-256v-170.667h256v170.667z" />
<glyph unicode="&#xe1109;" glyph-name="icon12-folder" d="M938.667 768h-341.333l-110.32 110.32c-33.2 33.2-98.667 60.347-145.68 60.347h-256c-47.073-0.136-85.197-38.26-85.333-85.32v-341.346c0.136 47.073 38.26 85.197 85.32 85.333h853.346c47.073-0.136 85.197-38.26 85.333-85.32v170.654c-0.136 47.073-38.26 85.197-85.32 85.333zM85.333 512h853.333c47.128 0 85.333-38.205 85.333-85.333v-426.667c0-47.128-38.205-85.333-85.333-85.333h-853.333c-47.128 0-85.333 38.205-85.333 85.333v426.667c0 47.128 38.205 85.333 85.333 85.333z" />
</font></defs></svg>
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -37,6 +37,8 @@
<glyph unicode="&#xe927;" glyph-name="icon-trash" d="M832 832h-192.36v64c0 35.2-28.8 64-64 64h-128c-35.2 0-64-28.8-64-64v-64h-191.64c-105.6 0-192-72-192-160s0-160 0-160h64v-384c0-105.6 86.4-192 192-192h512c105.6 0 192 86.4 192 192v384h64c0 0 0 72 0 160s-86.4 160-192 160zM320 128h-128v384h128v-384zM576 128h-128v384h128v-384zM832 128h-128v384h128v-384z" />
<glyph unicode="&#xe928;" glyph-name="icon-x" d="M384 448l-365.332-365.332c-24.89-24.89-24.89-65.62 0-90.51l37.49-37.49c24.89-24.89 65.62-24.89 90.51 0 0 0 365.332 365.332 365.332 365.332l365.332-365.332c24.89-24.89 65.62-24.89 90.51 0l37.49 37.49c24.89 24.89 24.89 65.62 0 90.51l-365.332 365.332c0 0 365.332 365.332 365.332 365.332 24.89 24.89 24.89 65.62 0 90.51l-37.49 37.49c-24.89 24.89-65.62 24.89-90.51 0 0 0-365.332-365.332-365.332-365.332l-365.332 365.332c-24.89 24.89-65.62 24.89-90.51 0l-37.49-37.49c-24.89-24.89-24.89-65.62 0-90.51 0 0 365.332-365.332 365.332-365.332z" />
<glyph unicode="&#xe929;" glyph-name="icon-brackets" d="M832 960h-192v-192h191.66l0.34-0.34v-639.32l-0.34-0.34h-191.66v-192h192c105.6 0 192 86.4 192 192v640c0 105.6-86.4 192-192 192zM384 128h-191.66l-0.34 0.34v639.32l0.34 0.34h191.66v192h-192c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h192v192z" />
<glyph unicode="&#xe930;" glyph-name="icon-crosshair" d="M574 962h-128v-320h128v320zM1022 514h-320v-128h320v128zM574 258h-128v-320h128v320zM318 514h-320v-128h320v128z" />
<glyph unicode="&#xe931;" glyph-name="icon-grippy-v2" horiz-adv-x="586" d="M146.4 777.2c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM146.4 557.8c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM146.4 338.2c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM146.4 118.8c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM365.8 886.8c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM365.8 667.4c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM365.8 448c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM365.8 228.6c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM365.8 9.2c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM585.2 777.2c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM585.2 557.8c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM585.2 338.2c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM585.2 118.8c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2z" />
<glyph unicode="&#xe1000;" glyph-name="icon-arrows-out" d="M0 448l256-256v512zM512 960l-256-256h512zM512-64l256 256h-512zM768 704v-512l256 256z" />
<glyph unicode="&#xe1001;" glyph-name="icon-arrows-right-left" d="M1024 448l-448-512v1024zM448 960l-448-512 448-512z" />
<glyph unicode="&#xe1002;" glyph-name="icon-arrows-up-down" d="M512 960l512-448h-1024zM0 384l512-448 512 448z" />
@@ -78,6 +80,13 @@
<glyph unicode="&#xe1039;" glyph-name="icon-brightness" d="M253.414 641.939l-155.172 116.384c-50.233-66.209-85.127-146.713-97.91-234.39l191.586-30.216c8.145 56.552 29.998 106.879 62.068 149.006zM191.98 402.283l-191.919-27.434c13.115-90.459 48.009-170.963 99.174-238.453l154.18 117.665c-31.476 41.347-53.309 91.675-61.231 146.504zM466.283 768.020l-27.434 191.919c-90.459-13.115-170.963-48.009-238.453-99.174l117.665-154.18c41.347 31.476 91.675 53.309 146.504 61.231zM822.323 861.758c-66.209 50.233-146.713 85.127-234.39 97.91l-30.216-191.586c56.552-8.145 106.879-29.998 149.006-62.068zM832.020 493.717l191.919 27.434c-13.115 90.459-48.009 170.963-99.174 238.453l-154.18-117.665c31.476-41.347 53.309-91.675 61.231-146.504zM201.677 34.242c66.209-50.233 146.713-85.127 234.39-97.91l30.216 191.586c-56.552 8.145-106.879 29.998-149.006 62.068zM770.586 254.061l155.131-116.343c50.233 66.209 85.127 146.713 97.91 234.39l-191.586 30.216c-8.125-56.564-29.966-106.906-62.028-149.049zM557.717 127.98l27.434-191.919c90.459 13.115 170.963 48.009 238.453 99.174l-117.665 154.18c-41.347-31.476-91.675-53.309-146.504-61.231zM770.586 448c0-142.813-115.773-258.586-258.586-258.586s-258.586 115.773-258.586 258.586c0 142.813 115.773 258.586 258.586 258.586s258.586-115.773 258.586-258.586z" />
<glyph unicode="&#xe1040;" glyph-name="icon-contrast" d="M512 960c-282.78 0-512-229.24-512-512s229.22-512 512-512 512 229.24 512 512-229.22 512-512 512zM783.52 176.48c-69.111-69.481-164.785-112.481-270.502-112.481-0.358 0-0.716 0-1.074 0.001l0.055 768c212.070-0.010 383.982-171.929 383.982-384 0-106.034-42.977-202.031-112.462-271.52z" />
<glyph unicode="&#xe1041;" glyph-name="icon-expand" d="M960 960c0 0 0 0 0 0h-320v-128h165.4l-210.6-210.8c-25-25-25-65.6 0-90.6 12.4-12.4 28.8-18.8 45.2-18.8s32.8 6.2 45.2 18.8l210.8 210.8v-165.4h128v384h-64zM896 154.6l-210.8 210.6c-25 25-65.6 25-90.6 0s-25-65.6 0-90.6l210.8-210.6h-165.4v-128h384v384h-128v-165.4zM218.6 832h165.4v128h-320c0 0 0 0 0 0h-64v-384h128v165.4l210.8-210.8c12.4-12.4 28.8-18.8 45.2-18.8s32.8 6.2 45.2 18.8c25 25 25 65.6 0 90.6l-210.6 210.8zM338.8 365.2l-210.8-210.6v165.4h-128v-384h384v128h-165.4l210.8 210.8c25 25 25 65.6 0 90.6-25.2 24.8-65.6 24.8-90.6-0.2z" />
<glyph unicode="&#xe1042;" glyph-name="icon-list-view" d="M0 896h1024v-128h-1024v128zM0 640h1024v-128h-1024v128zM0 384h1024v-128h-1024v128zM0 128h1024v-128h-1024v128z" />
<glyph unicode="&#xe1043;" glyph-name="icon-grid-snap-to" d="M382 130h448v448h-448v-448zM510 450h192v-192h-192v192zM-2 386h320v-64h-320v64zM894 386h128v-64h-128v64zM574 962h64v-320h-64v320zM574 66h64v-128h-64v128zM574 386h64v-64h-64v64z" />
<glyph unicode="&#xe1044;" glyph-name="icon-grid-snap-no" d="M768 384h192v-64h-192v64zM256 384h192v-64h-192v64zM0 384h192v-64h-192v64zM640 448h-64v-64h-64v-64h64v-64h64v64h64v64h-64zM576 704h64v-192h-64v192zM576 960h64v-192h-64v192zM576 192h64v-192h-64v192z" />
<glyph unicode="&#xe1045;" glyph-name="icon-frame-show" d="M0 896v-896h1024v896h-1024zM896 128h-768v640h768v-640zM192 704h384v-128h-384v128z" />
<glyph unicode="&#xe1046;" glyph-name="icon-frame-hide" d="M128 770h420l104 128h-652v-802.4l128 157.4zM896 130h-420l-104-128h652v802.4l-128-157.4zM832 962l-832-1024h192l832 1024zM392 578l104 128h-304v-128z" />
<glyph unicode="&#xe1047;" glyph-name="icon-import" d="M832 767.6v-639.4c0-0.2-0.2-0.2-0.4-0.4h-319.6v-192h320c105.6 0 192 86.4 192 192v640.2c0 105.6-86.4 192-192 192h-320v-192h319.6c0.2 0 0.4-0.2 0.4-0.4zM192 256v-192l384 384-384 384v-192h-192v-384z" />
<glyph unicode="&#xe1048;" glyph-name="icon-export" d="M192 128.34v639.32l0.34 0.34h319.66v192h-320c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h320v192h-319.66zM1024 448l-384 384v-192h-192v-384h192v-192l384 384z" />
<glyph unicode="&#xe1100;" glyph-name="icon-activity" d="M576 896h-256l320-320h-290.256c-44.264 76.516-126.99 128-221.744 128h-128v-512h128c94.754 0 177.48 51.484 221.744 128h290.256l-320-320h256l448 448-448 448z" />
<glyph unicode="&#xe1101;" glyph-name="icon-activity-mode" d="M512 960c-214.866 0-398.786-132.372-474.744-320h90.744c56.86 0 107.938-24.724 143.094-64h240.906l-192 192h256l320-320-320-320h-256l192 192h-240.906c-35.156-39.276-86.234-64-143.094-64h-90.744c75.958-187.628 259.878-320 474.744-320 282.77 0 512 229.23 512 512s-229.23 512-512 512z" />
<glyph unicode="&#xe1102;" glyph-name="icon-autoflow-tabular" d="M192 960c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h64v1024h-64zM384 960h256v-1024h-256v1024zM832 960h-64v-704h256v512c0 105.6-86.4 192-192 192z" />
@@ -108,4 +117,5 @@
<glyph unicode="&#xe1127;" glyph-name="icon-timer-v1.5" horiz-adv-x="896" d="M576 813.4v82.58c0 35.346-28.654 64-64 64h-128c-35.346 0-64-28.654-64-64v-82.58c-185.040-55.080-320-226.48-320-429.42 0-247.42 200.58-448 448-448s448 200.58 448 448c0 202.96-135 374.4-320 429.42zM468 363.98l-263.76-211c-57.105 59.935-92.24 141.251-92.24 230.772 0 0.080 0 0.16 0 0.24 0 185.268 150.72 335.988 336 335.988 6.72 0 13.38-0.22 20-0.62v-355.38z" />
<glyph unicode="&#xe1128;" glyph-name="icon-topic" d="M454.36 483.36l86.3 86.3c9.088 8.965 21.577 14.502 35.36 14.502s26.272-5.537 35.366-14.507l86.294-86.294c19.328-19.358 42.832-34.541 69.047-44.082l1.313 171.722-57.64 57.64c-34.407 34.33-81.9 55.558-134.35 55.558s-99.943-21.228-134.354-55.562l-86.296-86.297c-9.088-8.965-21.577-14.502-35.36-14.502s-26.272 5.537-35.366 14.507l-28.674 28.654v-172.14c19.045-7.022 41.040-11.084 63.984-11.084 52.463 0 99.966 21.239 134.379 55.587zM505.64 412.64l-86.3-86.3c-9.088-8.965-21.577-14.502-35.36-14.502s-26.272 5.537-35.366 14.507l-86.294 86.294c-2 2-4.2 4-6.36 6v-197.36c33.664-30.72 78.65-49.537 128.031-49.537 52.44 0 99.923 21.22 134.333 55.541l86.296 86.296c9.088 8.965 21.577 14.502 35.36 14.502s26.272-5.537 35.366-14.507l86.294-86.294c2-2 4.2-4 6.36-6v197.36c-33.664 30.72-78.65 49.537-128.031 49.537-52.44 0-99.923-21.22-134.333-55.541zM832 960h-128v-192h127.66l0.34-0.34v-639.32l-0.34-0.34h-127.66v-192h128c105.6 0 192 86.4 192 192v640c0 105.6-86.4 192-192 192zM320 128h-127.66l-0.34 0.34v639.32l0.34 0.34h127.66v192h-128c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h128v192z" />
<glyph unicode="&#xe1129;" glyph-name="icon-box-with-dashed-lines" d="M0 576h128v-256h-128v256zM128 831.78l0.22 0.22h191.78v128h-192c-70.606-0.215-127.785-57.394-128-127.979v-192.021h128v191.78zM128 64.22v191.78h-128v-192c0.215-70.606 57.394-127.785 127.979-128h192.021v128h-191.78zM384 960h256v-128h-256v128zM896 64.22l-0.22-0.22h-191.78v-128h192c70.606 0.215 127.785 57.394 128 127.979v192.021h-128v-191.78zM896 960h-192v-128h191.78l0.22-0.22v-191.78h128v192c-0.215 70.606-57.394 127.785-127.979 128zM896 576h128v-256h-128v256zM384 64h256v-128h-256v128zM256 704h512v-512h-512v512z" />
</font></defs></svg>
<glyph unicode="&#xe1130;" glyph-name="icon-summary-widget" d="M896 960h-768c-70.4 0-128-57.6-128-128v-768c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v768c0 70.4-57.6 128-128 128zM847.8 349.6l-82.6-143.2-189.6 131.6 19.2-230h-165.4l19.2 230-189.6-131.6-82.6 143.2 208.6 98.4-208.8 98.4 82.6 143.2 189.6-131.6-19.2 230h165.4l-19.2-230 189.6 131.6 82.6-143.2-208.6-98.4 208.8-98.4z" />
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

@@ -21,7 +21,7 @@
*****************************************************************************/
/********************************************* COLUMN LAYOUTS STYLES */
/*@mixin cols($totalCols, $span) {
@mixin cols($totalCols, $span) {
$cw: 100% / $totalCols;
min-width: (500px / $totalCols) * $span;
@if ($totalCols != $span) {
@@ -89,7 +89,7 @@
@include clearfix;
padding: $interiorMargin 0;
}
}*/
}
/********************************************* FLEX STYLES */
.l-flex-row,

View File

@@ -21,7 +21,7 @@
*****************************************************************************/
/************************** FEATURES */
$enableImageryThumbs: false; // Set to true if historical imagery thumbnails are supported
$enableImageryThumbs: true; // Set to true if historical imagery thumbnails are supported
/************************** VERY INFLUENTIAL GLOBAL DIMENSIONS */
$bodyMargin: 10px;
@@ -82,7 +82,7 @@ $tabularTdPadTB: 2px;
/*************** Imagery */
$imageMainControlBarH: 25px;
$imageThumbsD: 120px;
$imageThumbsWrapperH: $imageThumbsD * 1.4;
$imageThumbsWrapperH: 155px;
$imageThumbPad: 1px;
/*************** Ticks */
$ticksH: 25px;

View File

@@ -21,32 +21,11 @@
*****************************************************************************/
.t-fixed-position {
&.l-fixed-position {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: auto;
height: auto;
.l-grid-holder {
position: relative;
height: 100%;
width: 100%;
.l-grid {
position: absolute;
height: 100%;
width: 100%;
pointer-events: none;
z-index: 0;
}
}
@extend .abs;
}
.l-fixed-position-item {
position: absolute;
border: 1px solid transparent;
&.s-not-selected {
opacity: 0.8;
}
@@ -105,37 +84,8 @@
}
}
}
.l-fixed-position-item-handle {
$brd: 1px solid $colorKey;
background: rgba($colorKey, 0.5);
cursor: crosshair;
border: $brd;
position: absolute;
}
}
.edit-mode .t-fixed-position {
&.l-fixed-position {
.l-grid-holder {
.l-grid {
&.l-grid-x {
@include bgTicks($colorGridLines, 'x');
}
&.l-grid-y {
@include bgTicks($colorGridLines, 'y');
}
}
}
}
.l-fixed-position-item {
&:not(.s-selected) {
border: 1px dotted rgba($colorKey, 0.75);
&:hover {
border: 1px dotted rgba($colorKey, 1.0);
}
}
}
.s-status-editing {
.l-fixed-position-item-handle.edit-corner { display: block; }
}

View File

@@ -81,12 +81,6 @@ input, textarea {
letter-spacing: inherit;
}
input[type="text"],
input[type="search"] {
vertical-align: baseline;
padding: $inputTextP;
}
h1, h2, h3 {
letter-spacing: 0.04em;
margin: 0;

View File

@@ -1,10 +1,38 @@
@mixin glyph($unicode, $family: 'symbolsfont') {
/*****************************************************************************
* 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.
*****************************************************************************/
@mixin glyphBefore($unicode, $family: 'symbolsfont') {
&:before {
content: $unicode;
font-family: $family;
}
}
@mixin glyphAfter($unicode, $family: 'symbolsfont') {
&:after {
content: $unicode;
font-family: $family;
}
}
/************************** CHAR UNICODES */
$glyph-icon-alert-rect: '\e900';
@@ -37,6 +65,8 @@ $glyph-icon-plus: '\e926';
$glyph-icon-trash: '\e927';
$glyph-icon-x: '\e928';
$glyph-icon-brackets: '\e929';
$glyph-icon-crosshair: '\e930';
$glyph-icon-grippy: '\e931';
$glyph-icon-arrows-out: '\e1000';
$glyph-icon-arrows-right-left: '\e1001';
$glyph-icon-arrows-up-down: '\e1002';
@@ -78,6 +108,13 @@ $glyph-icon-x-in-circle: '\e1038';
$glyph-icon-brightness: '\e1039';
$glyph-icon-contrast: '\e1040';
$glyph-icon-expand: '\e1041';
$glyph-icon-list-view: '\e1042';
$glyph-icon-grid-snap-to: '\e1043';
$glyph-icon-grid-snap-no: '\e1044';
$glyph-icon-frame-show: '\e1045';
$glyph-icon-frame-hide: '\e1046';
$glyph-icon-import: '\e1047';
$glyph-icon-export: '\e1048';
$glyph-icon-activity: '\e1100';
$glyph-icon-activity-mode: '\e1101';
$glyph-icon-autoflow-tabular: '\e1102';
@@ -108,114 +145,122 @@ $glyph-icon-timeline: '\e1126';
$glyph-icon-timer: '\e1127';
$glyph-icon-topic: '\e1128';
$glyph-icon-box-with-dashed-lines: '\e1129';
$glyph-icon-summary-widget: '\e1130';
/************************** 16 PX CLASSES */
.icon-alert-rect { @include glyph($glyph-icon-alert-rect); }
.icon-alert-triangle { @include glyph($glyph-icon-alert-triangle); }
.icon-arrow-down { @include glyph($glyph-icon-arrow-down); }
.icon-arrow-left { @include glyph($glyph-icon-arrow-left); }
.icon-arrow-right { @include glyph($glyph-icon-arrow-right); }
.icon-arrow-double-up { @include glyph($glyph-icon-arrow-double-up); }
.icon-arrow-tall-up { @include glyph($glyph-icon-arrow-tall-up); }
.icon-arrow-tall-down { @include glyph($glyph-icon-arrow-tall-down); }
.icon-arrow-double-down { @include glyph($glyph-icon-arrow-double-down); }
.icon-arrow-up { @include glyph($glyph-icon-arrow-up); }
.icon-asterisk { @include glyph($glyph-icon-asterisk); }
.icon-bell { @include glyph($glyph-icon-bell); }
.icon-box { @include glyph($glyph-icon-box); }
.icon-box-with-arrow { @include glyph($glyph-icon-box-with-arrow); }
.icon-check { @include glyph($glyph-icon-check); }
.icon-connectivity { @include glyph($glyph-icon-connectivity); }
.icon-database-in-brackets { @include glyph($glyph-icon-database-in-brackets); }
.icon-eye-open { @include glyph($glyph-icon-eye-open); }
.icon-gear { @include glyph($glyph-icon-gear); }
.icon-hourglass { @include glyph($glyph-icon-hourglass); }
.icon-info { @include glyph($glyph-icon-info); }
.icon-link { @include glyph($glyph-icon-link); }
.icon-lock { @include glyph($glyph-icon-lock); }
.icon-minus { @include glyph($glyph-icon-minus); }
.icon-people { @include glyph($glyph-icon-people); }
.icon-person { @include glyph($glyph-icon-person); }
.icon-plus { @include glyph($glyph-icon-plus); }
.icon-trash { @include glyph($glyph-icon-trash); }
.icon-x { @include glyph($glyph-icon-x); }
.icon-brackets { @include glyph($glyph-icon-brackets); }
.icon-arrows-out { @include glyph($glyph-icon-arrows-out); }
.icon-arrows-right-left { @include glyph($glyph-icon-arrows-right-left); }
.icon-arrows-up-down { @include glyph($glyph-icon-arrows-up-down); }
.icon-bullet { @include glyph($glyph-icon-bullet); }
.icon-calendar { @include glyph($glyph-icon-calendar); }
.icon-chain-links { @include glyph($glyph-icon-chain-links); }
.icon-collapse-pane-left { @include glyph($glyph-icon-collapse-pane-left); }
.icon-collapse-pane-right { @include glyph($glyph-icon-collapse-pane-right); }
.icon-download { @include glyph($glyph-icon-download); }
.icon-duplicate { @include glyph($glyph-icon-duplicate); }
.icon-folder-new { @include glyph($glyph-icon-folder-new); }
.icon-fullscreen-collapse { @include glyph($glyph-icon-fullscreen-collapse); }
.icon-fullscreen-expand { @include glyph($glyph-icon-fullscreen-expand); }
.icon-layers { @include glyph($glyph-icon-layers); }
.icon-line-horz { @include glyph($glyph-icon-line-horz); }
.icon-magnify { @include glyph($glyph-icon-magnify); }
.icon-magnify-in { @include glyph($glyph-icon-magnify-in); }
.icon-magnify-out { @include glyph($glyph-icon-magnify-out); }
.icon-menu-hamburger { @include glyph($glyph-icon-menu-hamburger); }
.icon-move { @include glyph($glyph-icon-move); }
.icon-new-window { @include glyph($glyph-icon-new-window); }
.icon-paint-bucket { @include glyph($glyph-icon-paint-bucket); }
.icon-pause { @include glyph($glyph-icon-pause); }
.icon-pencil { @include glyph($glyph-icon-pencil); }
.icon-play { @include glyph($glyph-icon-play); }
.icon-plot-resource { @include glyph($glyph-icon-plot-resource); }
.icon-pointer-left { @include glyph($glyph-icon-pointer-left); }
.icon-pointer-right { @include glyph($glyph-icon-pointer-right); }
.icon-refresh { @include glyph($glyph-icon-refresh); }
.icon-save { @include glyph($glyph-icon-save); }
.icon-sine { @include glyph($glyph-icon-sine); }
.icon-T { @include glyph($glyph-icon-T); }
.icon-thumbs-strip { @include glyph($glyph-icon-thumbs-strip); }
.icon-two-parts-both { @include glyph($glyph-icon-two-parts-both); }
.icon-two-parts-one-only { @include glyph($glyph-icon-two-parts-one-only); }
.icon-resync { @include glyph($glyph-icon-resync); }
.icon-reset { @include glyph($glyph-icon-reset); }
.icon-x-in-circle { @include glyph($glyph-icon-x-in-circle); }
.icon-brightness { @include glyph($glyph-icon-brightness); }
.icon-contrast { @include glyph($glyph-icon-contrast); }
.icon-expand { @include glyph($glyph-icon-expand); }
.icon-activity { @include glyph($glyph-icon-activity); }
.icon-activity-mode { @include glyph($glyph-icon-activity-mode); }
.icon-autoflow-tabular { @include glyph($glyph-icon-autoflow-tabular); }
.icon-clock { @include glyph($glyph-icon-clock); }
.icon-database { @include glyph($glyph-icon-database); }
.icon-database-query { @include glyph($glyph-icon-database-query); }
.icon-dataset { @include glyph($glyph-icon-dataset); }
.icon-datatable { @include glyph($glyph-icon-datatable); }
.icon-dictionary { @include glyph($glyph-icon-dictionary); }
.icon-folder { @include glyph($glyph-icon-folder); }
.icon-image { @include glyph($glyph-icon-image); }
.icon-layout { @include glyph($glyph-icon-layout); }
.icon-object { @include glyph($glyph-icon-object); }
.icon-object-unknown { @include glyph($glyph-icon-object-unknown); }
.icon-packet { @include glyph($glyph-icon-packet); }
.icon-page { @include glyph($glyph-icon-page); }
.icon-plot-overlay { @include glyph($glyph-icon-plot-overlay); }
.icon-plot-stacked { @include glyph($glyph-icon-plot-stacked); }
.icon-session { @include glyph($glyph-icon-session); }
.icon-tabular { @include glyph($glyph-icon-tabular); }
.icon-tabular-lad { @include glyph($glyph-icon-tabular-lad); }
.icon-tabular-lad-set { @include glyph($glyph-icon-tabular-lad-set); }
.icon-tabular-realtime { @include glyph($glyph-icon-tabular-realtime); }
.icon-tabular-scrolling { @include glyph($glyph-icon-tabular-scrolling); }
.icon-telemetry { @include glyph($glyph-icon-telemetry); }
.icon-telemetry-panel { @include glyph($glyph-icon-telemetry-panel); }
.icon-timeline { @include glyph($glyph-icon-timeline); }
.icon-timer { @include glyph($glyph-icon-timer); }
.icon-topic { @include glyph($glyph-icon-topic); }
.icon-box-with-dashed-lines { @include glyph($glyph-icon-box-with-dashed-lines); }
.icon-alert-rect { @include glyphBefore($glyph-icon-alert-rect); }
.icon-alert-triangle { @include glyphBefore($glyph-icon-alert-triangle); }
.icon-arrow-down { @include glyphBefore($glyph-icon-arrow-down); }
.icon-arrow-left { @include glyphBefore($glyph-icon-arrow-left); }
.icon-arrow-right { @include glyphBefore($glyph-icon-arrow-right); }
.icon-arrow-double-up { @include glyphBefore($glyph-icon-arrow-double-up); }
.icon-arrow-tall-up { @include glyphBefore($glyph-icon-arrow-tall-up); }
.icon-arrow-tall-down { @include glyphBefore($glyph-icon-arrow-tall-down); }
.icon-arrow-double-down { @include glyphBefore($glyph-icon-arrow-double-down); }
.icon-arrow-up { @include glyphBefore($glyph-icon-arrow-up); }
.icon-asterisk { @include glyphBefore($glyph-icon-asterisk); }
.icon-bell { @include glyphBefore($glyph-icon-bell); }
.icon-box { @include glyphBefore($glyph-icon-box); }
.icon-box-with-arrow { @include glyphBefore($glyph-icon-box-with-arrow); }
.icon-check { @include glyphBefore($glyph-icon-check); }
.icon-connectivity { @include glyphBefore($glyph-icon-connectivity); }
.icon-database-in-brackets { @include glyphBefore($glyph-icon-database-in-brackets); }
.icon-eye-open { @include glyphBefore($glyph-icon-eye-open); }
.icon-gear { @include glyphBefore($glyph-icon-gear); }
.icon-hourglass { @include glyphBefore($glyph-icon-hourglass); }
.icon-info { @include glyphBefore($glyph-icon-info); }
.icon-link { @include glyphBefore($glyph-icon-link); }
.icon-lock { @include glyphBefore($glyph-icon-lock); }
.icon-minus { @include glyphBefore($glyph-icon-minus); }
.icon-people { @include glyphBefore($glyph-icon-people); }
.icon-person { @include glyphBefore($glyph-icon-person); }
.icon-plus { @include glyphBefore($glyph-icon-plus); }
.icon-trash { @include glyphBefore($glyph-icon-trash); }
.icon-x { @include glyphBefore($glyph-icon-x); }
.icon-brackets { @include glyphBefore($glyph-icon-brackets); }
.icon-crosshair { @include glyphBefore($glyph-icon-crosshair); }
.icon-grippy { @include glyphBefore($glyph-icon-grippy); }
.icon-arrows-out { @include glyphBefore($glyph-icon-arrows-out); }
.icon-arrows-right-left { @include glyphBefore($glyph-icon-arrows-right-left); }
.icon-arrows-up-down { @include glyphBefore($glyph-icon-arrows-up-down); }
.icon-bullet { @include glyphBefore($glyph-icon-bullet); }
.icon-calendar { @include glyphBefore($glyph-icon-calendar); }
.icon-chain-links { @include glyphBefore($glyph-icon-chain-links); }
.icon-collapse-pane-left { @include glyphBefore($glyph-icon-collapse-pane-left); }
.icon-collapse-pane-right { @include glyphBefore($glyph-icon-collapse-pane-right); }
.icon-download { @include glyphBefore($glyph-icon-download); }
.icon-duplicate { @include glyphBefore($glyph-icon-duplicate); }
.icon-folder-new { @include glyphBefore($glyph-icon-folder-new); }
.icon-fullscreen-collapse { @include glyphBefore($glyph-icon-fullscreen-collapse); }
.icon-fullscreen-expand { @include glyphBefore($glyph-icon-fullscreen-expand); }
.icon-layers { @include glyphBefore($glyph-icon-layers); }
.icon-line-horz { @include glyphBefore($glyph-icon-line-horz); }
.icon-magnify { @include glyphBefore($glyph-icon-magnify); }
.icon-magnify-in { @include glyphBefore($glyph-icon-magnify-in); }
.icon-magnify-out { @include glyphBefore($glyph-icon-magnify-out); }
.icon-menu-hamburger { @include glyphBefore($glyph-icon-menu-hamburger); }
.icon-move { @include glyphBefore($glyph-icon-move); }
.icon-new-window { @include glyphBefore($glyph-icon-new-window); }
.icon-paint-bucket { @include glyphBefore($glyph-icon-paint-bucket); }
.icon-pause { @include glyphBefore($glyph-icon-pause); }
.icon-pencil { @include glyphBefore($glyph-icon-pencil); }
.icon-play { @include glyphBefore($glyph-icon-play); }
.icon-plot-resource { @include glyphBefore($glyph-icon-plot-resource); }
.icon-pointer-left { @include glyphBefore($glyph-icon-pointer-left); }
.icon-pointer-right { @include glyphBefore($glyph-icon-pointer-right); }
.icon-refresh { @include glyphBefore($glyph-icon-refresh); }
.icon-save { @include glyphBefore($glyph-icon-save); }
.icon-sine { @include glyphBefore($glyph-icon-sine); }
.icon-T { @include glyphBefore($glyph-icon-T); }
.icon-thumbs-strip { @include glyphBefore($glyph-icon-thumbs-strip); }
.icon-two-parts-both { @include glyphBefore($glyph-icon-two-parts-both); }
.icon-two-parts-one-only { @include glyphBefore($glyph-icon-two-parts-one-only); }
.icon-resync { @include glyphBefore($glyph-icon-resync); }
.icon-reset { @include glyphBefore($glyph-icon-reset); }
.icon-x-in-circle { @include glyphBefore($glyph-icon-x-in-circle); }
.icon-brightness { @include glyphBefore($glyph-icon-brightness); }
.icon-contrast { @include glyphBefore($glyph-icon-contrast); }
.icon-expand { @include glyphBefore($glyph-icon-expand); }
.icon-list-view { @include glyphBefore($glyph-icon-list-view); }
.icon-grid-snap-to { @include glyphBefore($glyph-icon-grid-snap-to); }
.icon-grid-snap-no { @include glyphBefore($glyph-icon-grid-snap-no); }
.icon-frame-show { @include glyphBefore($glyph-icon-frame-show); }
.icon-frame-hide { @include glyphBefore($glyph-icon-frame-hide); }
.icon-import { @include glyphBefore($glyph-icon-import); }
.icon-export { @include glyphBefore($glyph-icon-export); }
.icon-activity { @include glyphBefore($glyph-icon-activity); }
.icon-activity-mode { @include glyphBefore($glyph-icon-activity-mode); }
.icon-autoflow-tabular { @include glyphBefore($glyph-icon-autoflow-tabular); }
.icon-clock { @include glyphBefore($glyph-icon-clock); }
.icon-database { @include glyphBefore($glyph-icon-database); }
.icon-database-query { @include glyphBefore($glyph-icon-database-query); }
.icon-dataset { @include glyphBefore($glyph-icon-dataset); }
.icon-datatable { @include glyphBefore($glyph-icon-datatable); }
.icon-dictionary { @include glyphBefore($glyph-icon-dictionary); }
.icon-folder { @include glyphBefore($glyph-icon-folder); }
.icon-image { @include glyphBefore($glyph-icon-image); }
.icon-layout { @include glyphBefore($glyph-icon-layout); }
.icon-object { @include glyphBefore($glyph-icon-object); }
.icon-object-unknown { @include glyphBefore($glyph-icon-object-unknown); }
.icon-packet { @include glyphBefore($glyph-icon-packet); }
.icon-page { @include glyphBefore($glyph-icon-page); }
.icon-plot-overlay { @include glyphBefore($glyph-icon-plot-overlay); }
.icon-plot-stacked { @include glyphBefore($glyph-icon-plot-stacked); }
.icon-session { @include glyphBefore($glyph-icon-session); }
.icon-tabular { @include glyphBefore($glyph-icon-tabular); }
.icon-tabular-lad { @include glyphBefore($glyph-icon-tabular-lad); }
.icon-tabular-lad-set { @include glyphBefore($glyph-icon-tabular-lad-set); }
.icon-tabular-realtime { @include glyphBefore($glyph-icon-tabular-realtime); }
.icon-tabular-scrolling { @include glyphBefore($glyph-icon-tabular-scrolling); }
.icon-telemetry { @include glyphBefore($glyph-icon-telemetry); }
.icon-telemetry-panel { @include glyphBefore($glyph-icon-telemetry-panel); }
.icon-timeline { @include glyphBefore($glyph-icon-timeline); }
.icon-timer { @include glyphBefore($glyph-icon-timer); }
.icon-topic { @include glyphBefore($glyph-icon-topic); }
.icon-box-with-dashed-lines { @include glyphBefore($glyph-icon-box-with-dashed-lines); }
.icon-summary-widget { @include glyphBefore($glyph-icon-summary-widget); }
/************************** 12 PX CLASSES */
.icon-eye-open-12px { @include glyph($glyph-icon-eye-open,'symbolsfont-12px'); }
.icon-collapse-pane-left-12px { @include glyph($glyph-icon-collapse-pane-left,'symbolsfont-12px'); }
.icon-collapse-pane-right-12px { @include glyph($glyph-icon-collapse-pane-right,'symbolsfont-12px'); }
.icon-folder-12px { @include glyph($glyph-icon-folder,'symbolsfont-12px'); }
.icon-crosshair-12px { @include glyphBefore($glyph-icon-crosshair,'symbolsfont-12px'); }
.icon-folder-12px { @include glyphBefore($glyph-icon-folder,'symbolsfont-12px'); }

View File

@@ -1,39 +0,0 @@
@mixin limitGlyph($iconColor, $glyph: $glyph-icon-alert-triangle) {
&:before {
color: $iconColor;
content: $glyph;
font-family: symbolsfont;
font-size: 0.8em;
display: inline;
margin-right: $interiorMarginSm;
}
}
.s-limit-red { background: $colorLimitRedBg !important; }
.s-limit-yellow { background: $colorLimitYellowBg !important; }
// Handle limit when applied to a tr
tr[class*="s-limit"] {
&.s-limit-red td:first-child {
@include limitGlyph($colorLimitRedIc);
}
&.s-limit-yellow td:first-child {
@include limitGlyph($colorLimitYellowIc);
}
&.s-limit-upr td:first-child:before { content: $glyph-icon-arrow-double-up; }
&.s-limit-lwr td:first-child:before { content: $glyph-icon-arrow-double-down; }
}
// Handle limit when applied directly to a non-tr element
// Assume this is applied to the element that displays the limit value
:not(tr)[class*="s-limit"] {
&.s-limit-red {
@include limitGlyph($colorLimitRedIc);
}
&.s-limit-yellow {
@include limitGlyph($colorLimitYellowIc);
}
&.s-limit-upr:before { content: $glyph-icon-arrow-double-up; }
&.s-limit-lwr:before { content: $glyph-icon-arrow-double-down; }
}

View File

@@ -27,7 +27,7 @@
@import "about";
@import "text";
@import "icons";
@import "limits";
@import "status";
@import "data-status";
@import "helpers/bubbles";
@import "helpers/splitter";
@@ -58,7 +58,6 @@
@import "search/search";
@import "mobile/search/search";
@import "overlay/overlay";
@import "mobile/overlay/overlay";
@import "tree/tree";
@import "object-label";
@import "mobile/tree";

View File

@@ -285,13 +285,14 @@
@mixin containerBase($bg: $colorBodyBg, $fg: $colorBodyFg) {
background-color: $bg;
border-radius: $controlCr;
//border-radius: $controlCr;
box-sizing: border-box;
color: $fg;
}
@mixin btnBase($bg: $colorBtnBg, $bgHov: $colorBtnBgHov, $fg: $colorBtnFg, $fgHov: $colorBtnFgHov, $ic: $colorBtnIcon, $icHov: $colorBtnIconHov) {
@include user-select(none);
border-radius: $controlCr;
color: $fg;
.icon,
&:before {

View File

@@ -0,0 +1,86 @@
/*****************************************************************************
* 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.
*****************************************************************************/
/*************************************************** MIXINS */
@mixin formulateStatusColors($c) {
// Sets bg and icon colors for elements
background: rgba($c, 0.4) !important;
&:before { color: $c !important; }
}
/*************************************************** GENERAL */
.s-limit-yellow,
.s-limit-red,
.s-limit-yellow-icon,
.s-limit-red-icon,
.s-status-warning-lo,
.s-status-warning-hi,
.s-status-diagnostic,
.s-status-command,
.s-status-info,
.s-status-ok,
.s-status-warning-lo-icon,
.s-status-warning-hi-icon,
.s-status-diagnostic-icon,
.s-status-command-icon,
.s-status-info-icon,
.s-status-ok-icon {
@include trans-prop-nice($props: background, $dur: 500ms);
&:before {
content:'';
font-family: symbolsfont;
font-size: 0.8em;
display: inline;
margin-right: $interiorMarginSm;
}
}
/*************************************************** LIMITS */
.s-limit-yellow, .s-limit-yellow-icon {
@include formulateStatusColors($colorWarningLo);
}
.s-limit-red, .s-limit-red-icon {
@include formulateStatusColors($colorWarningHi);
}
.s-limit-upr:before { content: $glyph-icon-arrow-double-up; }
.s-limit-lwr:before { content: $glyph-icon-arrow-double-down; }
.s-limit-yellow-icon:before,
.s-limit-red-icon:before { content: $glyph-icon-alert-triangle; }
/*************************************************** STATUS */
.s-status-warning-hi, .s-status-warning-hi-icon { @include formulateStatusColors($colorWarningHi); }
.s-status-warning-lo, .s-status-warning-lo-icon { @include formulateStatusColors($colorWarningLo); }
.s-status-diagnostic, .s-status-diagnostic-icon { @include formulateStatusColors($colorDiagnostic); }
.s-status-info, .s-status-info-icon { @include formulateStatusColors($colorInfo); }
.s-status-ok, .s-status-ok-icon { @include formulateStatusColors($colorOk); }
.s-status-warning-hi-icon:before { content: $glyph-icon-alert-triangle; }
.s-status-warning-lo-icon:before { content: $glyph-icon-alert-rect; }
.s-status-diagnostic-icon:before { content: $glyph-icon-eye-open; }
.s-status-info-icon:before { content: $glyph-icon-info; }
.s-status-ok-icon:before { content: $glyph-icon-check; }

View File

@@ -72,6 +72,15 @@
}
}
.s-hyperlink {
// Hyperlink objects
&:not(.s-button) {
color: $colorKey;
font-size: 0.8rem;
&:hover { color: $colorKeyHov; }
}
}
.s-icon-button {
// Clickable icon elements that have hover
@extend .ui-symbol;
@@ -224,18 +233,28 @@ textarea {
/******************************************************** INPUTS */
input[type="text"],
input[type="search"] {
input[type="search"],
input[type="number"] {
@include nice-input();
vertical-align: baseline;
padding: $inputTextP;
&.numeric {
text-align: right;
}
}
.l-input-sm {
input[type="text"],
input[type="search"],
input[type="number"] {
width: 50px !important;
}
}
.l-input-lg input[type="text"],
input[type="text"].lg { width: 100% !important; }
.l-input-med input[type="text"],
input[type="text"].med { width: 200px !important; }
.l-input-sm input[type="text"],
input[type="text"].sm { width: 50px !important; }
.l-numeric input[type="text"],
input[type="text"].numeric { text-align: right; }
@@ -297,6 +316,40 @@ textarea.lg { position: relative; height: 300px; }
}
}
/******************************************************** AUTOCOMPLETE */
.autocomplete {
input {
width: 226px;
padding: 5px 0px 5px 7px;
}
.icon-arrow-down {
position: absolute;
top: 8px;
left: 210px;
font-size: 10px;
cursor: pointer;
}
.autocompleteOptions {
border: 1px solid $colorFormLines;
border-radius: 5px;
width: 224px;
max-height: 170px;
overflow-y: auto;
overflow-x: hidden;
li {
border: 1px solid $colorFormLines;
padding: 8px 0px 8px 5px;
.optionText {
cursor: pointer;
}
}
.optionPreSelected {
background-color: $colorInspectorSectionHeaderBg;
color: $colorInspectorSectionHeaderFg;
}
}
}
/******************************************************** OBJECT-HEADER */
.object-header {
font-size: 1em;
@@ -651,10 +704,6 @@ textarea {
}
}
.view-switcher {
@include trans-prop-nice-fade($controlFadeMs);
}
/******************************************************** BROWSER ELEMENTS */
body.desktop {
::-webkit-scrollbar {

View File

@@ -249,7 +249,7 @@
.context-menu-holder,
.menu-holder {
position: absolute;
z-index: 70;
z-index: 120;
.context-menu-wrapper {
position: absolute;
height: 100%;
@@ -273,7 +273,7 @@
.btn-bar.right .menu,
.menus-to-left .menu {
z-index: 79;
z-index: 79;
left: auto;
right: 0;
width: auto;

View File

@@ -39,7 +39,7 @@
// Status coloring
.ok, .info {
.status-indicator {
color: $colorStatusInfo;
color: $colorInfo;
}
}
@@ -224,15 +224,15 @@
}
&.ok,
&.info {
@include statusBannerColors($colorStatusInfo);
@include statusBannerColors($colorInfo);
}
&.caution,
&.warning,
&.alert {
@include statusBannerColors($colorStatusAlert);
@include statusBannerColors($colorWarningLo);
}
&.error {
@include statusBannerColors($colorStatusError);
@include statusBannerColors($colorWarningHi);
}
}
@@ -248,15 +248,15 @@
.message-severity-info .type-icon.message-type {
@extend .icon-info;
color: $colorStatusInfo;
color: $colorInfo;
}
.message-severity-alert .type-icon.message-type {
@extend .icon-bell;
color: $colorStatusAlert;
color: $colorWarningLo;
}
.message-severity-error .type-icon.message-type {
@extend .icon-alert-rect;
color: $colorStatusError;
color: $colorWarningHi;
}
}
/* Paths:
@@ -311,6 +311,24 @@ body.desktop .t-message-single {
}
}
@include phonePortrait {
.t-message-single {
.l-message {
@include flex-direction(column);
.message-contents { margin-left: 0; }
}
.type-icon.message-type {
margin-bottom: $interiorMarginLg;
width: 100%;
text-align: center;
}
.bottom-bar {
text-align: center !important;
}
}
}
// Messages in list
.t-message-list {
@include messageBlock(32px);
@@ -350,7 +368,6 @@ body.desktop .t-message-list {
.s-unsynced {
$c: $colorPausedBg;
border: 1px solid $c;
@include animTo($animName: pulsePaused, $propName: border-color, $propValStart: rgba($c, 0.8), $propValEnd: rgba($c, 0.5), $dur: $animPausedPulseDur, $dir: alternate, $count: infinite);
}
.s-status-timeconductor-unsynced {

View File

@@ -19,12 +19,24 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
.s-status-editing .l-object-wrapper,
.edit-main {
// .s-status-editing .l-object-wrapper is relevant to New Edit Mode;
// .edit-main is legacy for old edit mode.
$handleD: 15px;
$cr: 5px;
.t-edit-handle-holder { display: none; }
.l-grid-holder {
display: none;
position: relative;
height: 100%;
width: 100%;
.l-grid {
@extend .abs;
pointer-events: none;
z-index: 0;
&.l-grid-y { background-position: 0 1px; }
}
}
.s-status-editing {
$handleD: 5px;
.t-edit-handle-holder { display: block; }
.edit-corner,
.edit-handle {
position: absolute;
@@ -32,81 +44,59 @@
}
.edit-corner {
background: rgba($colorSelectableSelectedPrimary, 0.5);
cursor: crosshair;
display: none; // Hide by default
border: 1px solid $colorSelectableSelectedPrimary;
width: $handleD;
height: $handleD;
$o: (-1 * $handleD) + 1px;
&:hover {
z-index: 11;
}
&.edit-resize-nw {
border-bottom-right-radius: $cr;
cursor: nw-resize;
top: 0; left: 0;
}
&.edit-resize-ne {
border-bottom-left-radius: $cr;
cursor: ne-resize;
top: 0; right: 0;
}
&.edit-resize-se {
border-top-left-radius: $cr;
cursor: se-resize;
bottom: 0; right: 0;
}
&.edit-resize-sw {
border-top-right-radius: $cr;
cursor: sw-resize;
bottom: 0; left: 0;
}
&.edit-resize-nw { top: $o; left: $o; }
&.edit-resize-ne { top: $o; right: $o; }
&.edit-resize-se { bottom: $o; right: $o; }
&.edit-resize-sw { bottom: $o; left: $o; }
}
.edit-handle {
top: $handleD; right: $handleD; bottom: $handleD; left: $handleD;
&.edit-move {
$m: 0; //$handleD;
cursor: move;
left: $m;
right: $m;
top: $m;
bottom: $m;
z-index: 1;
}
&.edit-resize-n {
top: 0px; bottom: auto;
height: $handleD;
cursor: n-resize;
}
&.edit-resize-e {
right: 0px; left: auto;
width: $handleD;
cursor: e-resize;
}
&.edit-resize-s {
bottom: 0px; top: auto;
height: $handleD;
cursor: s-resize;
}
&.edit-resize-w {
left: 0px; right: auto;
width: $handleD;
cursor: w-resize;
}
.edit-handle.edit-move {
// main move box for the whole frame element
$m: 0;
left: $m;
right: $m;
top: $m;
bottom: $m;
z-index: 1;
}
.frame.child-frame.panel {
&:hover {
@include boxShdwLarge();
border-color: $colorSelectableSelectedPrimary;
.view-switcher {
opacity: 1;
}
.edit-corner {
background-color: rgba($colorKey, 0.8);
&:hover {
background-color: rgba($colorKey, 1);
}
}
}
}
// Editing Grids
.l-grid-holder {
display: block;
.l-grid {
&.l-grid-x { @include bgTicks($colorGridLines, 'x'); }
&.l-grid-y { @include bgTicks($colorGridLines, 'y'); }
}
}
// Prevent nested frames from showing their grids
.t-frame-outer .l-grid-holder { display: none !important; }
// Prevent nested elements from showing s-hover-border
.t-frame-outer .s-hover-border {
border: none !important;
}
// Prevent nested frames from being selectable until we have proper sub-object editing
.t-frame-outer .t-frame-outer {
pointer-events: none;
}
}

View File

@@ -9,7 +9,6 @@
@if $enableImageryThumbs == true {
bottom: $interiorMargin*2 + $imageThumbsWrapperH;
}
min-height: 100px;
min-width: 150px;
.l-image-main {
background-color: $colorPlotBg;
@@ -22,7 +21,9 @@
.l-image-thumbs-wrapper {
top: auto;
height: $imageThumbsWrapperH;
min-height: $imageThumbsWrapperH;
max-height: 60%;
box-sizing: border-box;
}
.l-date,
@@ -43,14 +44,16 @@
.l-image-main-controlbar {
font-size: 0.8em;
line-height: inherit;
.left, .right {
.l-datetime-w, .l-controls-w {
direction: rtl;
overflow: hidden;
}
.left {
.l-datetime-w {
@include ellipsize();
margin-right: $interiorMarginSm;
text-align: left;
}
.right {
.l-controls-w {
z-index: 2;
}
.l-date,
@@ -82,20 +85,26 @@
/*************************************** THUMBS */
.l-image-thumbs-wrapper {
//@include test(green);
direction: rtl;
overflow-x: auto;
overflow-y: hidden;
overflow-x: hidden;
overflow-y: auto;
padding-bottom: $interiorMargin;
white-space: nowrap;
z-index: 70;
}
.l-image-thumb-item {
@include transition(background-color, 0.25s);
box-sizing: border-box;
cursor: pointer;
direction: ltr;
display: inline-block;
float: left;
font-size: 0.8em;
padding: 1px;
position: relative;
margin-left: $interiorMarginSm;
position: relative;
text-align: left;
width: $imageThumbsD + $imageThumbPad*2;
white-space: normal;
.l-thumb,
.l-date,
.l-time {
@@ -105,16 +114,9 @@
.l-time {
padding: 2px 3px;
}
cursor: pointer;
direction: ltr;
display: inline-block;
font-size: 0.8em;
margin-left: $interiorMarginSm;
text-align: left;
width: $imageThumbsD + $imageThumbPad*2;
white-space: normal;
&:hover {
background: rgba(#fff, 0.2);
background: $colorThumbHoverBg;
.l-date,
.l-time {
color: #fff;
@@ -138,6 +140,7 @@
/*************************************** LOCAL CONTROLS */
.l-local-controls {
max-width: 200px;
min-width: 100px;
width: 35%;
input[type="range"] {
display: block;
@@ -186,7 +189,8 @@
/*************************************** WHEN IN FRAME */
.frame .t-imagery {
.l-image-main-wrapper {
bottom: 0;
bottom: 0 !important;
height: 100% !important;
.l-image-main-controlbar {
font-size: 0.7em;
}
@@ -196,7 +200,8 @@
}
}
}
.l-image-thumbs-wrapper {
.l-image-thumbs-wrapper,
mct-splitter {
display: none;
}
}

View File

@@ -1,33 +1,36 @@
.l-time-display {
$transTime: 200ms;
$controlSize: 14px;
$control1ControlW: $controlSize + $interiorMargin;
$control2ControlW: $control1ControlW * 2;
line-height: 140%;
&:hover {
.l-btn.control {
.l-btn.controls {
opacity: 1;
}
}
&.l-timer {
.l-value:before,
.control {
font-size: 0.8em;
}
.l-value:before {
// Direction +/- element
font-size: $controlSize;
margin-right: $interiorMarginSm;
}
.control {
.controls {
@include trans-prop-nice((width, opacity), $transTime);
font-size: $controlSize;
line-height: inherit;
margin-right: 0;
opacity: 0;
width: 0;
.flex-elem {
margin-right: $interiorMargin;
}
}
&:hover .control {
margin-right: $interiorMargin;
&:hover .controls {
opacity: 1;
width: 1em;
width: $control2ControlW;
}
}
@@ -35,4 +38,34 @@
color: pullForward($colorBodyFg, 50%);
font-weight: 400;
}
// States
&.s-state-stopped,
&.s-state-paused {
.l-value {
opacity: 0.4;
}
}
&.s-state-started {
.l-value {
opacity: 1;
}
}
&.s-state-stopped {
// Hide Stop button, 1controlW
.t-btn-stop {
display: none;
}
&:hover .controls { width: $control1ControlW; }
}
&.s-state-paused {
// Paused, do something visual
.l-value {
&:before { @extend .pulse; }
}
}
}

View File

@@ -19,44 +19,40 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
@mixin labelValidate($sym, $c) {
> .label {
@include glyphAfter($sym);
&:after {
color: $c;
margin-left: $interiorMargin;
}
}
}
mct-form.validates {
.form-row.validates {
> .label {
padding-right: $reqSymbolM; // Keep room for validation element
&:before {
position: absolute;
right: $interiorMargin;
&:after {
font-size: $reqSymbolFontSize;
height: 100%;
line-height: 200%;
}
}
&.invalid,
&.invalid.req {
> .label {
@extend .icon-x;
&:before {
color: $colorFormInvalid;
}
}
}
&.invalid.req { @include labelValidate($glyph-icon-x, $colorFormInvalid); }
&.valid,
&.valid.req {
> .label {
@extend .icon-check;
&:before {
color: $colorFormValid;
}
}
}
&.req {
> .label {
@extend .icon-asterisk;
&:before {
color: $colorFormRequired;
}
}
}
&.valid.req { @include labelValidate($glyph-icon-check, $colorFormValid); }
&.req { @include labelValidate($glyph-icon-asterisk, $colorFormRequired); }
}
}
body.desktop .form-row.validates > .label {
&:after {
position: absolute;
right: $interiorMargin;
height: 100%;
line-height: 200%;
}
}

View File

@@ -132,5 +132,33 @@
}
}
}
}
table.list-view {
$s: 1.2em;
width: 100%;
th, td {
cursor: pointer;
}
tr:hover td {
background-color: $colorItemBg;
color: $colorItemFg;
}
td {
$p: $interiorMargin;
@include ellipsize;
color: $colorItemFg;
font-size: 1em;
line-height: $s;
max-width: 0;
padding-top: $p;
padding-bottom: $p;
}
.t-item-icon {
font-size: $s;
margin-right: $interiorMargin;
}
.t-title-label {
@include ellipsize; // Yep, need it here too as well as the <td>
}
}

View File

@@ -92,7 +92,7 @@ body.mobile {
}
.object-browse-bar {
margin-left: 45px;
&.t-primary { margin-left: 45px; }
.context-available {
opacity: 1 !important;
}

View File

@@ -1,74 +0,0 @@
@include phoneandtablet {
.overlay {
.clk-icon.close {
top: $mobileOverlayMargin; right: $mobileOverlayMargin;
}
> .holder {
height: 90%; width: 90%;
> .contents {
top: $mobileOverlayMargin;
right: $mobileOverlayMargin;
bottom: $mobileOverlayMargin;
left: $mobileOverlayMargin;
.top-bar {
> .title {
margin-right: 1.2em;
}
}
}
}
}
}
@include phone {
.overlay > .holder {
$m: 0;
border-radius: $m;
top: $m;
right: $m;
bottom: $m;
left: $m;
height: auto; width: auto;
min-width: 200px; min-height: 200px;
max-height: 100%; max-width: 100%;
overflow: auto;
@include transform(none);
.editor .form .form-row.l-flex-row {
// Display elements in a columnar view
@include flex-direction(column);
> .flex-elem {
&:not(:first-child) {
margin-top: $interiorMargin;
}
&.label {
width: 100%;
}
&.controls {
overflow: auto;
}
}
&.validates > .label:before {
position: relative;
right: auto;
line-height: inherit;
margin-right: $interiorMargin;
}
}
}
.t-dialog-sm .overlay > .holder {
height: auto; max-height: 100%;
}
}
@include phonePortrait {
.overlay > .holder {
.contents .bottom-bar {
text-align: center;
}
}
}

View File

@@ -21,11 +21,16 @@
*****************************************************************************/
.overlay {
font-size: 90%;
&.delayEntry100ms {
@include keyframes(fadeInFromNone) {
0% { display: none; opacity: 0; }
100% { display: block; opacity: 1; }
0% {
display: none;
opacity: 0;
}
100% {
display: block;
opacity: 1;
}
}
@include animation-delay($delayEntryMs);
@include animation(fadeInFromNone $durEntryMs ease-in);
@@ -35,29 +40,21 @@
z-index: 100;
}
.close {
font-size: 0.8rem;
$d: $interiorMargin;
opacity: 0.3;
position: absolute;
top: $interiorMarginLg;
right: $interiorMarginLg;
top: $d;
right: $d;
bottom: auto;
left: auto;
z-index: 100;
&:hover {
opacity: 0.6;
}
}
> .holder {
@include containerSubtle($colorOvrBg, $colorOvrFg);
border-radius: $basicCr * 3;
color: $colorOvrFg;
top: 50%;
right: auto;
bottom: auto;
left: 50%;
@include transform(translateX(-50%) translateY(-50%));
height: 70%;
width: 50%;
min-height: 300px;
min-width: 600px;
z-index: 101;
> .contents {
> .abs.outer-holder {
z-index: 102;
> .abs.inner-holder {
$m: $overlayMargin;
top: $m;
right: $m;
@@ -65,78 +62,186 @@
left: $m;
}
}
.title {
@include ellipsize();
font-size: 1.2em;
line-height: 120%;
margin-bottom: $interiorMargin;
}
.hint, .field-hints { color: $colorFieldHintOverlay !important; }
.abs.top-bar {
height: $ovrTopBarH;
}
.abs.editor,
.abs.message-body {
top: $ovrTopBarH + $interiorMarginLg;
bottom: $ovrFooterH + $interiorMarginLg;
left: 0;
right: 0;
overflow: auto;
.field.l-input-med {
input[type='text'] {
width: 100%;
}
}
}
.bottom-bar {
text-align: right;
.s-button {
$bg: $colorOvrBtnBg;
&:not(.major) {
@include btnSubtle($bg, pullForward($bg, 10%), $colorOvrBtnFg, $colorOvrBtnFg);
}
font-size: 95%;
height: $ovrFooterH;
line-height: $ovrFooterH;
margin-left: $interiorMargin;
margin-bottom: $interiorMarginSm;
padding: 0 $interiorMargin * 3;
&:first-child {
margin-left: 0;
&:not(:last-child) {
margin-right: $interiorMargin;
}
}
}
// Dialog boxes, size constrained and centered in desktop/tablet
&.l-dialog {
.s-button {
&:not(.major) {
@include btnSubtle($bg: $colorOvrBtnBg, $bgHov: pullForward($colorOvrBtnBg, 10%), $fg: $colorOvrBtnFg, $fgHov: $colorOvrBtnFg, $ic: $colorOvrBtnFg, $icHov: $colorOvrBtnFg);
}
}
> .abs.outer-holder {
@include desktopandtablet {
$max: 1280px;
@include transform(translateX(-50%) translateY(-50%));
border-radius: $overlayCr;
top: 50%; right: auto; bottom: auto; left: 50%;
width: 70%; height: 70%;
min-width: 520px;
max-width: $max; max-height: $max;
}
@include phone {
overflow: auto;
.editor .form .form-row.l-flex-row {
// Display elements in a columnar view
@include flex-direction(column);
> .flex-elem {
&:not(:first-child) {
margin-top: $interiorMargin;
}
&.label {
width: 100%;
}
&.controls {
overflow: auto;
}
}
&.validates > .label:before {
position: relative;
right: auto;
line-height: inherit;
margin-right: $interiorMargin;
}
}
}
@include containerSubtle($colorOvrBg, $colorOvrFg);
}
.title {
@include ellipsize();
font-size: 1.2em;
line-height: 120%;
margin-bottom: $interiorMargin;
}
.hint, .field-hints {
color: $colorFieldHintOverlay !important;
}
.abs.top-bar {
height: $ovrTopBarH;
}
.abs.bottom-bar {
top: auto;
right: 0;
bottom: 0;
left: 0;
overflow: visible;
height: $ovrFooterH;
}
.abs.editor,
.abs.message-body {
top: $ovrTopBarH + $interiorMarginLg;
bottom: $ovrFooterH + $interiorMarginLg;
left: 0;
right: 0;
overflow: auto;
.field.l-input-med {
input[type='text'] {
width: 100%;
}
}
}
.l-progress-bar {
$h: $progressBarHOverlay;
display: block;
height: $h;
line-height: $h;
margin: .5em 0;
width: 100%;
}
.select {
box-shadow: $shdwBtnsOverlay;
}
}
.abs.bottom-bar {
top: auto;
right: 0;
bottom: 0;
left: 0;
overflow: visible;
height: $ovrFooterH;
// Large view overlays for mobile and desktop
&.l-large-view {
> .abs.outer-holder {
@include keyframes(overlayIn) {
from {
opacity: 0;
transform: scale(0, 0);
}
to {
opacity: 1;
transform: scale(1.0, 1.0);
}
}
@include animToParams(overlayIn, $dur: $durLargeViewExpand, $delay: 0);
background: $colorBodyBg;
z-index: 101;
.abs.inner-holder {
opacity: 0;
@include keyframes(contentsIn) {
from { opacity: 0; }
to { opacity: 1; }
}
@include animToParams(contentsIn, $dur: 50ms, $delay: $durLargeViewExpand * 1.25);
}
// Hide View Large button
.t-btn-view-large {
display: none;
}
// But show View Large button when it's nested inside a Layout
.t-frame-inner .t-frame-inner .t-btn-view-large { display: block; }
}
}
// When multiple Large Views are visible, hide the blocker for all but the first
& + .l-large-view {
.blocker {
display: none;
}
}
}
body.desktop {
.overlay {
> .abs.outer-holder {
border-radius: $overlayCr;
}
&.l-large-view {
> .abs.outer-holder {
width: 90%;
height: 90%;
top: 5%;
left: 5%;
@include boxShdwLarge();
}
}
}
.l-progress-bar {
$h: $progressBarHOverlay;
display: block;
.t-dialog-sm .overlay > .outer-holder {
// Used for blocker and in-progress dialogs, modal alerts, etc.
$h: 225px;
max-height: $h;
height: $h;
line-height: $h;
margin: .5em 0;
width: 100%;
}
.select {
box-shadow: $shdwBtnsOverlay;
}
}
.t-dialog-sm .overlay > .holder {
// Used for blocker and in-progress dialogs, modal alerts, etc.
$h: 225px;
min-height: $h;
height: $h;
}

View File

@@ -20,69 +20,139 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
.frame {
$ohH: $btnFrameH;
$bc: $colorInteriorBorder;
&.child-frame.panel {
background: $colorBodyBg;
border: 1px solid $bc;
$ohH: $btnFrameH;
$bc: $colorInteriorBorder;
&.child-frame.panel {
z-index: 0; // Needed to prevent child-frame controls from showing through when another child-frame is above
&:hover {
border-color: lighten($bc, 10%);
}
}
.object-top-bar {
font-size: 0.75em;
height: $ohH;
line-height: $ohH;
.left {
padding-right: $interiorMarginLg;
&:not(.no-frame) {
background: $colorBodyBg;
border: 1px solid $bc;
&:hover {
border-color: lighten($bc, 10%);
}
}
}
>.object-holder.abs {
top: $ohH + $interiorMargin;
}
.contents {
$myM: $interiorMargin;
top: $myM;
right: $myM;
bottom: $myM;
left: $myM;
}
&.frame-template {
.s-button,
.s-menu-button {
height: $ohH;
line-height: $ohH;
padding: 0 $interiorMargin;
> span,
}
.object-browse-bar {
font-size: 0.75em;
height: $ohH;
line-height: $ohH;
.right {
@include trans-prop-nice-fade($controlFadeMs);
padding-left: $interiorMargin;
}
}
&.t-object-type-timer,
&.t-object-type-clock,
&.t-object-type-hyperlink {
// Hide the right side buttons for objects where they don't make sense
// Note that this will hide the view Switcher button if applied
// to an object that it.
.object-browse-bar .right { display: none; }
}
> .object-holder.abs {
top: $ohH + $interiorMargin;
}
.contents {
$m: $interiorMargin;
top: $m;
right: $m;
bottom: $m;
left: $m;
}
&.frame-template {
.s-button,
.s-menu-button {
height: $ohH;
line-height: $ohH;
padding: 0 $interiorMargin;
> span,
&:before {
font-size: 0.65rem;
}
}
font-size: 0.65rem;
}
}
.s-menu-button:after {
font-size: 8px;
}
.s-menu-button:after {
font-size: 8px;
}
.view-switcher {
z-index: 10;
}
}
.view-switcher {
// Hide the name when the view switcher is in a frame context
.title-label {
display: none;
}
}
.view-switcher {
z-index: 10;
}
}
.view-switcher {
margin-right: $interiorMargin; // Kick other top bar elements away when I'm present.
// Hide the name when the view switcher is in a frame context
.title-label {
display: none;
}
}
&.no-frame {
background: transparent !important;
border: none !important;
.object-browse-bar .right {
$m: 0; // $interiorMarginSm;
background: rgba(black, 0.3);
border-radius: $basicCr;
padding: $interiorMarginSm;
position: absolute;
top: $m; right: $m;
z-index: 2;
}
&.t-frame-outer > .t-rep-frame {
&.contents {
$m: 2px;
top: $m;
right: $m;
bottom: $m;
left: $m;
}
> .t-frame-inner {
> .object-browse-bar .left {
display: none;
}
> .object-holder.abs {
top: 0 !important;
}
}
}
}
/********************************************************** OBJECT TYPES */
.t-object-type-hyperlink {
.s-hyperlink.s-button {
// When a hyperlink is a button in a frame, make it expand to fill out to the object-holder
@extend .abs;
.label {
@include ellipsize();
@include transform(translateY(-50%));
padding: 0 $interiorMargin;
position: absolute;
min-width: 0;
left: 0; right: 0;
text-align: center;
top: 50%;
}
}
}
}
body.desktop .frame {
// Hide local controls initially and show it them on hover when they're in an element that's in a frame context
// Frame template is used because we need to target the lowest nested frame
.object-browse-bar .btn-bar {
opacity: 0;
pointer-events: none;
}
// Target the first descendant so that we only show the elements in the outermost container.
// Handles the case where we have layouts in layouts.
&:hover > .object-browse-bar {
.btn-bar {
opacity: 1;
pointer-events: inherit;
}
}
}
body.desktop .frame.frame-template {
// Hide the view switcher by default when it's in an element that's in a frame context
// Frame template is used because we need to target the lowest nested frame
.view-switcher {
opacity: 0;
}
&:hover .view-switcher {
// Show the view switcher on frame hover
opacity: 1;
}
}

View File

@@ -136,14 +136,6 @@
.mini-tab-icon.toggle-pane {
z-index: 5;
}
&.items {
.object-browse-bar {
.left.abs,
.right.abs {
top: auto;
}
}
}
}
body.desktop .pane .mini-tab-icon.toggle-pane {
@@ -235,8 +227,13 @@ body.desktop .pane .mini-tab-icon.toggle-pane {
top: $ueTopBarH + $interiorMarginLg;
}
.l-object-wrapper-inner {
@include trans-prop-nice-resize(0.25s);
.l-object-wrapper {
padding: 0;
@include trans-prop-nice((padding), 0.25s);
.l-edit-controls {
@include trans-prop-nice((height), 0.5s);
height: 0;
}
}
.object-browse-bar .s-button,
@@ -250,10 +247,9 @@ body.desktop .pane .mini-tab-icon.toggle-pane {
vertical-align: top;
}
.object-browse-bar,
.top-bar {
.view-switcher {
margin-right: $interiorMarginLg * 2;
.object-browse-bar {
.l-object-action-buttons {
margin-left: $interiorMarginLg; // Kick the view switcher and other elements away
}
}
@@ -265,7 +261,6 @@ body.desktop .pane .mini-tab-icon.toggle-pane {
white-space: nowrap;
.left {
padding-right: $interiorMarginLg;
.l-back {
margin-right: $interiorMarginLg;
&.s-status-editing { display: none; }
@@ -348,53 +343,21 @@ body.desktop {
.pane:not(.resizing) {
@include trans-prop-nice-resize-w(250ms);
}
.pane.primary-pane .object-browse-bar {
.pane.primary-pane > .object-browse-bar {
min-width: 200px; // Needed for nice display when primary pane is constrained severely via splitters
}
}
.s-status-editing {
.l-object-wrapper {
$t2Dur: $browseToEditAnimMs;
$t1Dur: $t2Dur / 2;
$pulseDur: $editBorderPulseMs;
$bC0: rgba($colorEditAreaFg, 0.5);
$bC100: rgba($colorEditAreaFg, 1);
background-color: $colorEditAreaBg;
border-radius: $controlCr;
border: 1px dotted $bC0;
// Transition 1
@include keyframes(wrapperIn) {
from { border: 0px dotted transparent; padding: 0; }
to { border: 1px dotted $bC0; padding: 5px; }
}
// Do last
@include keyframes(pulseNew) {
from { border-color: $bC0; }
to { border-color: $bC100; }
}
@include animation-name(wrapperIn, pulseNew);
@include animation-duration($t1Dur, $pulseDur);
@include animation-delay(0s, $t1Dur + $t2Dur);
@include animation-direction(normal, alternate);
@include animation-fill-mode(both, none);
@include animation-iteration-count(1, infinite);
@include animation-timing-function(ease-in-out, linear);
border: 1px dotted $colorEditAreaFg;
padding: $interiorMargin;
.l-edit-controls {
height: 0;
height: $ueEditToolBarH + $interiorMargin; margin-bottom: $interiorMargin;
border-bottom: 1px solid $colorInteriorBorder;
// Transition 2: reveal edit controls
@include keyframes(editIn) {
from { border-bottom: 0px solid transparent; height: 0; margin-bottom: 0; }
to { border-bottom: 1px solid $colorInteriorBorder; height: $ueEditToolBarH + $interiorMargin; margin-bottom: $interiorMargin; }
}
@include animToParams(editIn, $dur: $t2Dur, $delay: $t1Dur);
.tool-bar {
right: $interiorMargin;
}

View File

@@ -19,21 +19,36 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
.s-selectable {
border: 1px solid transparent;
.s-hover-border {
border: 1px dotted transparent;
}
&.s-hover {
// Styles when hovering over a selectable object
border-color: $colorSelectableHov !important;
.s-status-editing {
// Limit to editing mode until we have sub-object selection
.s-hover-border {
// Show a border by default so user can see object bounds and empty objects
border: 1px dotted rgba($colorSelectableSelectedPrimary, 0.3) !important;
&:hover {
border-color: rgba($colorSelectableSelectedPrimary, 0.7) !important;
}
}
&.s-selected {
.s-selected > .s-hover-border,
.s-selected.s-hover-border {
// Styles for a selected object. Also used by legacy Fixed Position/Panel objects.
border-color: $colorSelectableSelectedPrimary !important;
@include boxShdwLarge();
// Show edit-corners if you got 'em
.edit-corner {
display: block;
&:hover {
background-color: rgba($colorKey, 1);
}
}
}
&.s-moveable {
@include boxShdwLarge();
.s-selected > .s-moveable,
.s-selected.s-moveable {
cursor: move;
}
}
}

View File

@@ -26,9 +26,11 @@
.l-control-group {
height: $btnToolbarH;
}
input[type="text"] {
input[type="text"],
input[type="search"],
input[type="number"] {
box-sizing: border-box;
font-size: .9em;
font-size: .8em;
height: $btnToolbarH;
margin-bottom: 1px;
position: relative;

View File

@@ -83,13 +83,14 @@ define(
// Callback to fire after each timeout;
// update bounds and schedule another timeout
function onInterval() {
if (!active) {
return;
}
fireEval({
width: element[0].offsetWidth,
height: element[0].offsetHeight
});
if (active) {
$timeout(onInterval, currentInterval(), false);
}
$timeout(onInterval, currentInterval(), false);
}
// Stop running in the background

View File

@@ -93,13 +93,21 @@ define(
* @memberof platform/commonUI/general
* @constructor
*/
function MCTSplitPane($parse, $log, $interval) {
function MCTSplitPane($parse, $log, $interval, $window) {
function controller($scope, $element, $attrs) {
var anchorKey = $attrs.anchor || DEFAULT_ANCHOR,
positionParsed = $parse($attrs.position),
anchor,
activeInterval,
positionParsed = $parse($attrs.position),
position; // Start undefined, until explicitly set
position,
splitterSize,
alias = $attrs.alias !== undefined ?
"mctSplitPane-" + $attrs.alias : undefined,
//convert string to number from localStorage
userWidthPreference = $window.localStorage.getItem(alias) === null ?
undefined : Number($window.localStorage.getItem(alias));
// Get relevant size (height or width) of DOM element
function getSize(domElement) {
@@ -109,16 +117,18 @@ define(
// Apply styles to child elements
function updateChildren(children) {
position = userWidthPreference || position;
// Pick out correct elements to update, flowing from
// selected anchor edge.
var first = children.eq(anchor.reversed ? 2 : 0),
splitter = children.eq(1),
last = children.eq(anchor.reversed ? 0 : 2),
splitterSize = getSize(splitter[0]),
firstSize;
splitterSize = getSize(splitter[0]);
first.css(anchor.edge, "0px");
first.css(anchor.dimension, (position - splitterSize) + 'px');
first.css(anchor.dimension, position + 'px');
// Get actual size (to obey min-width etc.)
firstSize = getSize(first[0]);
@@ -126,10 +136,9 @@ define(
splitter.css(anchor.edge, firstSize + 'px');
splitter.css(anchor.opposite, "auto");
last.css(anchor.edge, (firstSize + splitterSize) + 'px');
last.css(anchor.opposite, "0px");
position = firstSize + splitterSize;
last.css(anchor.edge, firstSize + splitterSize + 'px');
last.css(anchor.opposite, '0px');
position = firstSize;
}
// Update positioning of contained elements
@@ -166,9 +175,22 @@ define(
positionParsed.assign($scope, position);
}
}
return position;
}
function setUserWidthPreference(value) {
if (alias) {
userWidthPreference = value;
}
}
function persistToLocalStorage(value) {
if (alias) {
$window.localStorage.setItem(alias, value);
}
}
// Dynamically apply a CSS class to elements when the user
// is actively resizing
function toggleClass(classToToggle) {
@@ -196,18 +218,31 @@ define(
activeInterval = $interval(function () {
getSetPosition(getSetPosition());
}, POLLING_INTERVAL, 0, false);
// ...and stop polling when we're destroyed.
$scope.$on('$destroy', function () {
$interval.cancel(activeInterval);
});
// Interface exposed by controller, for mct-splitter to user
return {
position: getSetPosition,
toggleClass: toggleClass,
anchor: function () {
return anchor;
},
position: function (newPosition) {
if (arguments.length === 0) {
return getSetPosition();
}
setUserWidthPreference(newPosition);
return getSetPosition(newPosition);
},
startResizing: function () {
toggleClass('resizing');
},
endResizing: function (finalPosition) {
persistToLocalStorage(finalPosition);
toggleClass('resizing');
}
};
}
@@ -219,9 +254,7 @@ define(
controller: ['$scope', '$element', '$attrs', controller]
};
}
return MCTSplitPane;
}
);

View File

@@ -37,15 +37,16 @@ define(
*/
function MCTSplitter() {
function link(scope, element, attrs, mctSplitPane) {
var initialPosition;
var initialPosition,
newPosition;
element.addClass("splitter");
scope.splitter = {
// Begin moving this splitter
startMove: function () {
mctSplitPane.startResizing();
initialPosition = mctSplitPane.position();
mctSplitPane.toggleClass('resizing');
},
// Handle user changes to splitter position
move: function (delta) {
@@ -55,12 +56,16 @@ define(
(anchor.reversed ? -1 : 1);
// Update the position of this splitter
mctSplitPane.position(initialPosition + pixelDelta);
newPosition = initialPosition + pixelDelta;
if (initialPosition !== newPosition) {
mctSplitPane.position(newPosition);
}
},
// Grab the event when the user is done moving
// the splitter and pass it on
endMove: function () {
mctSplitPane.toggleClass('resizing');
mctSplitPane.endResizing(newPosition);
}
};
}
@@ -83,4 +88,3 @@ define(
}
);

View File

@@ -102,11 +102,16 @@ define(
// Broadcast a destroy event
mockScope.$on.mostRecentCall.args[1]();
testElement.offsetWidth = 300;
testElement.offsetHeight = 350;
mockScope.$eval.reset();
// Fire the timeout
mockTimeout.mostRecentCall.args[0]();
// Should NOT have scheduled another timeout
expect(mockTimeout.calls.length).toEqual(2);
expect(mockScope.$eval).not.toHaveBeenCalled();
});
it("triggers a digest cycle when size changes", function () {

View File

@@ -38,7 +38,8 @@ define(
mockLog,
mockInterval,
mockParsed,
mctSplitPane;
mctSplitPane,
mockWindow = {};
beforeEach(function () {
mockParse = jasmine.createSpy('$parse');
@@ -48,13 +49,23 @@ define(
mockInterval.cancel = jasmine.createSpy('mockCancel');
mockParsed = jasmine.createSpy('parsed');
mockParsed.assign = jasmine.createSpy('assign');
mockParse.andReturn(mockParsed);
mockWindow.localStorage = {
store: {},
setItem: function (key, value) {
this.store[key] = value;
},
getItem: function (key) {
return this.store[key];
}
};
mctSplitPane = new MCTSplitPane(
mockParse,
mockLog,
mockInterval
mockInterval,
mockWindow
);
});
@@ -85,7 +96,7 @@ define(
jasmine.createSpyObj('$scope', ['$apply', '$watch', '$on']);
mockElement =
jasmine.createSpyObj('element', JQLITE_METHODS);
testAttrs = {};
testAttrs = {alias: 'rightSide'};
mockChildren =
jasmine.createSpyObj('children', JQLITE_METHODS);
mockFirstPane =
@@ -129,7 +140,7 @@ define(
it("exposes its splitter's initial position", function () {
expect(controller.position()).toEqual(
mockFirstPane[0].offsetWidth + mockSplitter[0].offsetWidth
mockFirstPane[0].offsetWidth
);
});
@@ -142,10 +153,14 @@ define(
});
});
it("allows classes to be toggled on contained elements", function () {
controller.toggleClass('resizing');
expect(mockChildren.toggleClass)
.toHaveBeenCalledWith('resizing');
it("applies resizing class to children when resizing", function () {
controller.startResizing();
expect(mockChildren.toggleClass).toHaveBeenCalledWith('resizing');
});
it("removes resizing class from children when resizing action ends", function () {
controller.endResizing(0);
expect(mockChildren.toggleClass).toHaveBeenCalledWith('resizing');
});
it("allows positions to be set", function () {
@@ -153,7 +168,7 @@ define(
controller.position(testValue);
expect(mockFirstPane.css).toHaveBeenCalledWith(
'width',
(testValue - mockSplitter[0].offsetWidth) + 'px'
(testValue) + 'px'
);
});
@@ -185,11 +200,11 @@ define(
mockFirstPane[0].offsetWidth += 100;
// Should not reflect the change yet
expect(controller.position()).not.toEqual(
mockFirstPane[0].offsetWidth + mockSplitter[0].offsetWidth
mockFirstPane[0].offsetWidth
);
mockInterval.mostRecentCall.args[0]();
expect(controller.position()).toEqual(
mockFirstPane[0].offsetWidth + mockSplitter[0].offsetWidth
mockFirstPane[0].offsetWidth
);
});
@@ -198,6 +213,12 @@ define(
fireOn('$destroy');
expect(mockInterval.cancel).toHaveBeenCalled();
});
it("saves user preference to localStorage when user is done resizing", function () {
controller.endResizing(100);
expect(Number(mockWindow.localStorage.getItem('mctSplitPane-rightSide'))).toEqual(100);
});
});
});

View File

@@ -57,7 +57,7 @@ define(
testAttrs = {};
mockSplitPane = jasmine.createSpyObj(
'mctSplitPane',
['position', 'toggleClass', 'anchor']
['position', 'startResizing', 'endResizing', 'anchor']
);
mctSplitter.link(
@@ -86,9 +86,9 @@ define(
mockScope.splitter.startMove();
});
it("adds a 'resizing' class", function () {
expect(mockSplitPane.toggleClass)
.toHaveBeenCalledWith('resizing');
it("tell's the splitter when it is resizing", function () {
expect(mockSplitPane.startResizing)
.toHaveBeenCalled();
});
it("repositions during drag", function () {
@@ -97,11 +97,10 @@ define(
.toHaveBeenCalledWith(testPosition + 10);
});
it("removes the 'resizing' class when finished", function () {
mockSplitPane.toggleClass.reset();
it("tell's the splitter when it is done resizing", function () {
mockScope.splitter.move([10,0]);
mockScope.splitter.endMove();
expect(mockSplitPane.toggleClass)
.toHaveBeenCalledWith('resizing');
expect(mockSplitPane.endResizing).toHaveBeenCalledWith(testPosition + 10);
});
});

View File

@@ -17,6 +17,7 @@ $hoverRatioPercent: 10%;
$basicCr: 3px;
$controlCr: 2px;
$smallCr: 2px;
$overlayCr: 11px;
// Buttons and Controls
$colorBtnBg: pullForward($colorBodyBg, $contrastRatioPercent);
@@ -52,9 +53,15 @@ $timeControllerToiLineColor: #00c2ff;
$timeControllerToiLineColorHov: #fff;
$colorTransLucBg: #666; // Used as a visual blocking element over variable backgrounds, like imagery
// General Colors
// Foundation Colors
$colorAlt1: #ffc700;
$colorAlert: #ff3c00;
$colorWarningHi: #cc0000;
$colorWarningLo: #ff9900;
$colorDiagnostic: #a4b442;
$colorCommand: #3693bd;
$colorInfo: #2294a2;
$colorOk: #33cc33;
$colorIconLink: #49dedb;
$colorPausedBg: #c56f01;
$colorPausedFg: #fff;
@@ -83,8 +90,8 @@ $colorCreateMenuText: $colorMenuFg;
// Form colors
$colorCheck: $colorKey;
$colorFormRequired: $colorAlt1;
$colorFormValid: #33cc33;
$colorFormError: #990000;
$colorFormValid: $colorOk;
$colorFormError: $colorWarningHi;
$colorFormInvalid: #ff3300;
$colorFormFieldErrorBg: $colorFormError;
$colorFormFieldErrorFg: rgba(#fff, 0.6);
@@ -108,8 +115,8 @@ $colorInspectorSectionHeaderFg: pullForward($colorInspectorBg, 40%);
// Status colors, mainly used for messaging and item ancillary symbols
$colorStatusFg: #ccc;
$colorStatusDefault: #ccc;
$colorStatusInfo: #62ba72;
$colorStatusAlert: #ffa66d;
$colorStatusInfo: $colorInfo;
$colorStatusAlert: $colorAlert;
$colorStatusError: #d4585c;
$colorStatusAvailable: $colorKey;
$colorStatusBtnBg: $colorBtnBg;
@@ -124,14 +131,14 @@ $animPausedPulseDur: 500ms;
$colorSelectBg: $colorBtnBg;
$colorSelectFg: $colorBtnFg;
// Limits and staleness colors
// Limits, status and staleness colors
$colorTelemFresh: pullForward($colorBodyFg, 20%);
$colorTelemStale: pushBack($colorBodyFg, 20%);
$styleTelemStale: italic;
$colorLimitYellowBg: rgba(#ffaa00, 0.3);
$colorLimitYellowIc: #ffaa00;
$colorLimitRedBg: rgba(red, 0.3);
$colorLimitRedIc: red;
$colorLimitYellowBg: rgba($colorWarningLo, 0.3);
$colorLimitYellowIc: $colorWarningLo;
$colorLimitRedBg: rgba($colorWarningHi, 0.3);
$colorLimitRedIc: $colorWarningHi;
// Bubble colors
$colorInfoBubbleBg: #ddd;
@@ -146,6 +153,7 @@ $colorOvrFg: pullForward($colorBodyFg, 30%);
$colorOvrBtnBg: pullForward($colorOvrBg, 20%);
$colorOvrBtnFg: #fff;
$colorFieldHintOverlay: pullForward($colorOvrBg, 30%);
$durLargeViewExpand: 250ms;
// Items
$colorItemBg: lighten($colorBodyBg, 5%);
@@ -189,6 +197,9 @@ $colorItemTreeVCHover: pullForward($colorItemTreeVC, 20%);
$colorItemTreeSelectedVC: $colorItemTreeVC;
$shdwItemTreeIcon: 0.6;
// Images
$colorThumbHoverBg: $colorItemTreeHoverBg;
// Scrollbar
$scrollbarTrackSize: 10px;
$scrollbarTrackShdw: rgba(#000, 0.7) 0 1px 5px;

View File

@@ -13,3 +13,10 @@
// For dark interfaces, darker things move back - opposite for light interfaces
@return darken($c, $p);
}
@function bgFg($c) {
// Given a single color, return valid background and foreground versions of that color
$bg: darken($c, 20%);
$fg: lighten($c, 20%);
@return $bg, $fg;
}

View File

@@ -17,6 +17,7 @@ $hoverRatioPercent: 10%;
$basicCr: 4px;
$controlCr: $basicCr;
$smallCr: 3px;
$overlayCr: 11px;
// Buttons and Controls
$colorBtnBg: pullForward($colorBodyBg, $contrastRatioPercent);
@@ -52,9 +53,15 @@ $timeControllerToiLineColor: $colorBodyFg;
$timeControllerToiLineColorHov: #0052b5;
$colorTransLucBg: #666; // Used as a visual blocking element over variable backgrounds, like imagery
// General Colors
// Foundation Colors
$colorAlt1: #776ba2;
$colorAlert: #ff3c00;
$colorWarningHi: #990000;
$colorWarningLo: #ff9900;
$colorDiagnostic: #a4b442;
$colorCommand: #3693bd;
$colorInfo: #2294a2;
$colorOk: #33cc33;
$colorIconLink: #49dedb;
$colorPausedBg: #ff9900;
$colorPausedFg: #fff;
@@ -83,8 +90,8 @@ $colorCreateMenuText: $colorBodyFg;
// Form colors
$colorCheck: $colorKey;
$colorFormRequired: $colorKey;
$colorFormValid: #33cc33;
$colorFormError: #990000;
$colorFormValid: $colorOk;
$colorFormError: $colorWarningHi;
$colorFormInvalid: #ff2200;
$colorFormFieldErrorBg: $colorFormError;
$colorFormFieldErrorFg: rgba(#fff, 0.6);
@@ -106,7 +113,7 @@ $colorInspectorSectionHeaderBg: pullForward($colorInspectorBg, 5%);
$colorInspectorSectionHeaderFg: pullForward($colorInspectorBg, 40%);
// Status colors, mainly used for messaging and item ancillary symbols
$colorStatusFg: #fff;
$colorStatusFg: #999;
$colorStatusDefault: #ccc;
$colorStatusInfo: #60ba7b;
$colorStatusAlert: #ffb66c;
@@ -146,6 +153,7 @@ $colorOvrFg: $colorBodyFg;
$colorOvrBtnBg: pullForward($colorOvrBg, 40%);
$colorOvrBtnFg: #fff;
$colorFieldHintOverlay: pullForward($colorOvrBg, 40%);
$durLargeViewExpand: 250ms;
// Items
$colorItemBg: #ddd;
@@ -189,6 +197,9 @@ $colorItemTreeVCHover: $colorKey;
$colorItemTreeSelectedVC: $colorBodyBg;
$shdwItemTreeIcon: none;
// Images
$colorThumbHoverBg: $colorItemTreeHoverBg;
// Scrollbar
$scrollbarTrackSize: 10px;
$scrollbarTrackShdw: rgba(#000, 0.2) 0 1px 2px;

View File

@@ -12,3 +12,11 @@
// For dark interfaces, darker things move back - opposite for light interfaces
@return lighten($c, $p);
}
@function bgFg($c) {
// Given a single color, return valid background and foreground versions of that color
$bg: darken($c, 20%);
$fg: lighten($c, 20%);
@return $bg, $fg;
}

View File

@@ -148,13 +148,19 @@ define(
*/
PersistenceCapability.prototype.refresh = function () {
var domainObject = this.domainObject;
var $q = this.$q;
// Update a domain object's model upon refresh
function updateModel(model) {
var modified = model.modified;
return domainObject.useCapability("mutation", function () {
return model;
}, modified);
if (model === undefined) {
//Get failed, reject promise
return $q.reject('Got empty object model');
} else {
var modified = model.modified;
return domainObject.useCapability("mutation", function () {
return model;
}, modified);
}
}
if (domainObject.getModel().persisted === undefined) {

View File

@@ -34,23 +34,32 @@ define([], function () {
transactionService,
cacheService
) {
function hasChanged(domainObject) {
var model = domainObject.getModel();
return model.persisted === undefined || model.modified > model.persisted;
}
var mutationTopic = topic('mutation');
mutationTopic.listen(function (domainObject) {
var persistence = domainObject.getCapability('persistence');
var wasActive = transactionService.isActive();
cacheService.put(domainObject.getId(), domainObject.getModel());
if (!wasActive) {
transactionService.startTransaction();
}
if (hasChanged(domainObject)) {
transactionService.addToTransaction(
persistence.persist.bind(persistence),
persistence.refresh.bind(persistence)
);
if (!wasActive) {
transactionService.startTransaction();
}
if (!wasActive) {
transactionService.commit();
transactionService.addToTransaction(
persistence.persist.bind(persistence),
persistence.refresh.bind(persistence)
);
if (!wasActive) {
transactionService.commit();
}
}
});
}

View File

@@ -65,6 +65,20 @@ define(['csv'], function (CSV) {
this.saveAs(blob, filename);
};
/**
* Export an object as a JSON file. Triggers a download using the function
* provided when the ExportService was instantiated.
*
* @param {Object} obj an object to be exported as JSON
* @param {ExportOptions} [options] additional parameters for the file
* export
*/
ExportService.prototype.exportJSON = function (obj, options) {
var filename = (options && options.filename) || "test-export.json";
var jsonText = JSON.stringify(obj);
var blob = new Blob([jsonText], {type: "application/json"});
this.saveAs(blob, filename);
};
/**
* Additional parameters for file export.
* @typedef ExportOptions

View File

@@ -21,6 +21,7 @@
*****************************************************************************/
define([
"moment-timezone",
"./src/indicators/ClockIndicator",
"./src/services/TickerService",
"./src/controllers/ClockController",
@@ -28,10 +29,13 @@ define([
"./src/controllers/RefreshingController",
"./src/actions/StartTimerAction",
"./src/actions/RestartTimerAction",
"./src/actions/StopTimerAction",
"./src/actions/PauseTimerAction",
"text!./res/templates/clock.html",
"text!./res/templates/timer.html",
'legacyRegistry'
], function (
MomentTimezone,
ClockIndicator,
TickerService,
ClockController,
@@ -39,6 +43,8 @@ define([
RefreshingController,
StartTimerAction,
RestartTimerAction,
StopTimerAction,
PauseTimerAction,
clockTemplate,
timerTemplate,
legacyRegistry
@@ -139,6 +145,17 @@ define([
"cssClass": "icon-play",
"priority": "preferred"
},
{
"key": "timer.pause",
"implementation": PauseTimerAction,
"depends": [
"now"
],
"category": "contextual",
"name": "Pause",
"cssClass": "icon-pause",
"priority": "preferred"
},
{
"key": "timer.restart",
"implementation": RestartTimerAction,
@@ -149,6 +166,17 @@ define([
"name": "Restart at 0",
"cssClass": "icon-refresh",
"priority": "preferred"
},
{
"key": "timer.stop",
"implementation": StopTimerAction,
"depends": [
"now"
],
"category": "contextual",
"name": "Stop",
"cssClass": "icon-box",
"priority": "preferred"
}
],
"types": [
@@ -200,13 +228,20 @@ define([
"cssClass": "l-inline"
}
]
},
{
"key": "timezone",
"name": "Timezone",
"control": "autocomplete",
"options": MomentTimezone.tz.names()
}
],
"model": {
"clockFormat": [
"YYYY/MM/DD hh:mm:ss",
"clock12"
]
],
"timezone": "UTC"
}
},
{

View File

@@ -19,11 +19,16 @@
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<div class="l-time-display l-digital l-timer s-timer" ng-controller="TimerController as timer">
<div class="l-time-display l-digital l-timer s-timer s-state-{{timer.timerState}}" ng-controller="TimerController as timer">
<div class="l-elem-wrapper l-flex-row">
<a ng-click="timer.clickButton()"
title="{{timer.buttonText()}}"
class="flex-elem control s-icon-button {{timer.buttonCssClass()}}"></a>
<div class="l-elem-wrapper l-flex-row controls">
<a ng-click="timer.clickStopButton()"
title="Stop"
class="flex-elem s-icon-button t-btn-stop icon-box"></a>
<a ng-click="timer.clickButton()"
title="{{timer.buttonText()}}"
class="flex-elem s-icon-button t-btn-pauseplay {{timer.buttonCssClass()}}"></a>
</div>
<span class="flex-elem l-value {{timer.signClass()}}">
<span class="value"
ng-class="{ active:timer.text() }">{{timer.text() || "--:--:--"}}

View File

@@ -25,13 +25,10 @@ define(
function () {
/**
* Implements the "Start" and "Restart" action for timers.
* Implements the "Pause" action for timers.
*
* Sets the reference timestamp in a timer to the current
* time, such that it begins counting up.
*
* Both "Start" and "Restart" share this implementation, but
* control their visibility with different `appliesTo` behavior.
* Sets the reference pausedTime in a timer to the current
* time, such that it stops counting up.
*
* @implements {Action}
* @memberof platform/features/clock
@@ -40,22 +37,35 @@ define(
* time (typically wrapping `Date.now`)
* @param {ActionContext} context the context for this action
*/
function AbstractStartTimerAction(now, context) {
function PauseTimerAction(now, context) {
this.domainObject = context.domainObject;
this.now = now;
}
AbstractStartTimerAction.prototype.perform = function () {
PauseTimerAction.appliesTo = function (context) {
var model =
(context.domainObject && context.domainObject.getModel()) ||
{};
// We show this variant for timers which have
// a target time, or is in a playing state.
return model.type === 'timer' &&
model.timerState === 'started';
};
PauseTimerAction.prototype.perform = function () {
var domainObject = this.domainObject,
now = this.now;
function setTimestamp(model) {
model.timestamp = now();
function updateModel(model) {
model.timerState = 'paused';
model.pausedTime = now();
}
return domainObject.useCapability('mutation', setTimestamp);
return domainObject.useCapability('mutation', updateModel);
};
return AbstractStartTimerAction;
return PauseTimerAction;
}
);

View File

@@ -21,8 +21,8 @@
*****************************************************************************/
define(
['./AbstractStartTimerAction'],
function (AbstractStartTimerAction) {
[],
function () {
/**
* Implements the "Restart at 0" action.
@@ -30,7 +30,6 @@ define(
* Behaves the same as (and delegates functionality to)
* the "Start" action.
*
* @extends {platform/features/clock.AbstractTimerAction}
* @implements {Action}
* @memberof platform/features/clock
* @constructor
@@ -39,24 +38,33 @@ define(
* @param {ActionContext} context the context for this action
*/
function RestartTimerAction(now, context) {
AbstractStartTimerAction.apply(this, [now, context]);
this.domainObject = context.domainObject;
this.now = now;
}
RestartTimerAction.prototype =
Object.create(AbstractStartTimerAction.prototype);
RestartTimerAction.appliesTo = function (context) {
var model =
(context.domainObject && context.domainObject.getModel()) ||
{};
// We show this variant for timers which already have
// a target time.
// We show this variant for timers which already have a target time.
return model.type === 'timer' &&
model.timestamp !== undefined;
model.timerState !== 'stopped';
};
RestartTimerAction.prototype.perform = function () {
var domainObject = this.domainObject,
now = this.now;
function updateModel(model) {
model.timestamp = now();
model.timerState = 'started';
model.pausedTime = undefined;
}
return domainObject.useCapability('mutation', updateModel);
};
return RestartTimerAction;
}
);

View File

@@ -21,8 +21,8 @@
*****************************************************************************/
define(
['./AbstractStartTimerAction'],
function (AbstractStartTimerAction) {
[],
function () {
/**
* Implements the "Start" action for timers.
@@ -30,7 +30,6 @@ define(
* Sets the reference timestamp in a timer to the current
* time, such that it begins counting up.
*
* @extends {platform/features/clock.AbstractTimerAction}
* @implements {Action}
* @memberof platform/features/clock
* @constructor
@@ -39,12 +38,10 @@ define(
* @param {ActionContext} context the context for this action
*/
function StartTimerAction(now, context) {
AbstractStartTimerAction.apply(this, [now, context]);
this.domainObject = context.domainObject;
this.now = now;
}
StartTimerAction.prototype =
Object.create(AbstractStartTimerAction.prototype);
StartTimerAction.appliesTo = function (context) {
var model =
(context.domainObject && context.domainObject.getModel()) ||
@@ -53,10 +50,28 @@ define(
// We show this variant for timers which do not yet have
// a target time.
return model.type === 'timer' &&
model.timestamp === undefined;
model.timerState !== 'started';
};
StartTimerAction.prototype.perform = function () {
var domainObject = this.domainObject,
now = this.now;
function updateModel(model) {
//if we are resuming
if (model.pausedTime) {
var timeShift = now() - model.pausedTime;
model.timestamp = model.timestamp + timeShift;
} else {
model.timestamp = now();
}
model.timerState = 'started';
model.pausedTime = undefined;
}
return domainObject.useCapability('mutation', updateModel);
};
return StartTimerAction;
}
);

View File

@@ -0,0 +1,71 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2009-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.
*****************************************************************************/
define(
[],
function () {
/**
* Implements the "Stop" action for timers.
*
* Sets the reference timestamp in a timer undefined,
* such that it is reset and makes no movements.
*
* @implements {Action}
* @memberof platform/features/clock
* @constructor
* @param {Function} now a function which returns the current
* time (typically wrapping `Date.now`)
* @param {ActionContext} context the context for this action
*/
function StopTimerAction(now, context) {
this.domainObject = context.domainObject;
this.now = now;
}
StopTimerAction.appliesTo = function (context) {
var model =
(context.domainObject && context.domainObject.getModel()) ||
{};
// We show this variant for timers which do not yet have
// a target time.
return model.type === 'timer' &&
model.timerState !== 'stopped';
};
StopTimerAction.prototype.perform = function () {
var domainObject = this.domainObject;
function updateModel(model) {
model.timestamp = undefined;
model.timerState = 'stopped';
model.pausedTime = undefined;
}
return domainObject.useCapability('mutation', updateModel);
};
return StopTimerAction;
}
);

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