diff --git a/example/generator/bundle.json b/example/generator/bundle.json index a13bbdc8f8..cdb4736957 100644 --- a/example/generator/bundle.json +++ b/example/generator/bundle.json @@ -34,6 +34,10 @@ { "key": "time", "name": "Time" + }, + { + "key": "yesterday", + "name": "Yesterday" } ], "ranges": [ @@ -61,4 +65,4 @@ } ] } -} \ No newline at end of file +} diff --git a/example/generator/src/SinewaveTelemetrySeries.js b/example/generator/src/SinewaveTelemetrySeries.js index 5b7914a867..1e84034766 100644 --- a/example/generator/src/SinewaveTelemetrySeries.js +++ b/example/generator/src/SinewaveTelemetrySeries.js @@ -29,23 +29,25 @@ define( function () { "use strict"; - var firstObservedTime = Math.floor(Date.now() / 1000); + var ONE_DAY = 60 * 60 * 24, + firstObservedTime = Math.floor(Date.now() / 1000) - ONE_DAY; /** * * @constructor */ function SinewaveTelemetrySeries(request) { - var latestObservedTime = Math.floor(Date.now() / 1000), + var timeOffset = (request.domain === 'yesterday') ? ONE_DAY : 0, + latestTime = Math.floor(Date.now() / 1000) - timeOffset, + firstTime = firstObservedTime - timeOffset, endTime = (request.end !== undefined) ? - Math.floor(request.end / 1000) : latestObservedTime, - count = - Math.min(endTime, latestObservedTime) - firstObservedTime, - period = request.period || 30, + Math.floor(request.end / 1000) : latestTime, + count = Math.min(endTime, latestTime) - firstTime, + period = +request.period || 30, generatorData = {}, - offset = (request.start !== undefined) ? - Math.floor(request.start / 1000) - firstObservedTime : - 0; + requestStart = (request.start === undefined) ? firstTime : + Math.max(Math.floor(request.start / 1000), firstTime), + offset = requestStart - firstTime; if (request.size !== undefined) { offset = Math.max(offset, count - request.size); @@ -56,8 +58,8 @@ define( }; generatorData.getDomainValue = function (i, domain) { - return (i + offset) * 1000 + - (domain !== 'delta' ? (firstObservedTime * 1000) : 0); + return (i + offset) * 1000 + firstTime * 1000 - + (domain === 'yesterday' ? ONE_DAY : 0); }; generatorData.getRangeValue = function (i, range) { diff --git a/platform/commonUI/general/res/sass/_mixins.scss b/platform/commonUI/general/res/sass/_mixins.scss index 070bf29e73..c3d2ecc781 100644 --- a/platform/commonUI/general/res/sass/_mixins.scss +++ b/platform/commonUI/general/res/sass/_mixins.scss @@ -375,20 +375,6 @@ overflow-y: $showBar; } -@mixin wait-spinner($b: 5px, $c: $colorAlt1) { - display: block; - position: absolute; - -webkit-animation: rotation .6s infinite linear; - -moz-animation: rotation .6s infinite linear; - -o-animation: rotation .6s infinite linear; - animation: rotation .6s infinite linear; - border-color: rgba($c, 0.25); - border-top-color: rgba($c, 1.0); - border-style: solid; - border-width: $b; - border-radius: 100%; -} - @mixin test($c: #ffcc00, $a: 0.2) { background-color: rgba($c, $a) !important; } diff --git a/platform/commonUI/general/res/sass/controls/_controls.scss b/platform/commonUI/general/res/sass/controls/_controls.scss index f5dc2e102f..eef87c3439 100644 --- a/platform/commonUI/general/res/sass/controls/_controls.scss +++ b/platform/commonUI/general/res/sass/controls/_controls.scss @@ -356,7 +356,7 @@ label.checkbox.custom { .l-month-year-pager { $pagerW: 20px; //@include test(); - font-size: 0.8rem; + //font-size: 0.8rem; height: $r1H; margin-bottom: $interiorMargin; position: relative; diff --git a/platform/commonUI/general/res/sass/controls/_time-controller.scss b/platform/commonUI/general/res/sass/controls/_time-controller.scss index 2167518494..75f9c2a872 100644 --- a/platform/commonUI/general/res/sass/controls/_time-controller.scss +++ b/platform/commonUI/general/res/sass/controls/_time-controller.scss @@ -10,8 +10,8 @@ } -.l-time-controller { - $minW: 400px; +mct-include.l-time-controller { + $minW: 500px; $knobHOffset: 0px; $knobM: ($sliderKnobW + $knobHOffset) * -1; $rangeValPad: $interiorMargin; @@ -22,11 +22,17 @@ $r2H: nth($ueTimeControlH,2); $r3H: nth($ueTimeControlH,3); - //height: $r1H + $r2H + $r3H + ($interiorMargin * 2); + @include absPosDefault(); + //@include test(); + display: block; + top: auto; + height: $r1H + $r2H + $r3H + ($interiorMargin * 2); + min-width: $minW; + font-size: 0.8rem; .l-time-range-inputs-holder, .l-time-range-slider { - font-size: 0.8em; + //font-size: 0.8em; } .l-time-range-inputs-holder, @@ -36,7 +42,6 @@ //@include test(); @include absPosDefault(0, visible); @include box-sizing(border-box); - min-width: $minW; top: auto; } .l-time-range-slider, @@ -141,7 +146,7 @@ @include webkitProp(transform, translateX(-50%)); color: $colorPlotLabelFg; display: inline-block; - font-size: 0.7em; + font-size: 0.9em; position: absolute; top: 8px; white-space: nowrap; diff --git a/platform/commonUI/general/res/sass/helpers/_wait-spinner.scss b/platform/commonUI/general/res/sass/helpers/_wait-spinner.scss index f80c1f1971..86c23a266a 100644 --- a/platform/commonUI/general/res/sass/helpers/_wait-spinner.scss +++ b/platform/commonUI/general/res/sass/helpers/_wait-spinner.scss @@ -19,24 +19,45 @@ * this source code distribution or the Licensing information page available * at runtime from the About dialog for additional information. *****************************************************************************/ -@-webkit-keyframes rotation { - from {-webkit-transform: rotate(0deg);} - to {-webkit-transform: rotate(359deg);} +@include keyframes(rotation) { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(359deg); } } -@-moz-keyframes rotation { - from {-moz-transform: rotate(0deg);} - to {-moz-transform: rotate(359deg);} +@mixin wait-spinner2($b: 5px, $c: $colorAlt1) { + @include keyframes(rotateCentered) { + 0% { transform: translateX(-50%) translateY(-50%) rotate(0deg); } + 100% { transform: translateX(-50%) translateY(-50%) rotate(359deg); } + } + @include animation-name(rotateCentered); + @include animation-duration(0.5s); + @include animation-iteration-count(infinite); + @include animation-timing-function(linear); + border-color: rgba($c, 0.25); + border-top-color: rgba($c, 1.0); + border-style: solid; + border-width: 5px; + @include border-radius(100%); + @include box-sizing(border-box); + display: block; + position: absolute; + height: 0; width: 0; + padding: 7%; + left: 50%; top: 50%; } -@-o-keyframes rotation { - from {-o-transform: rotate(0deg);} - to {-o-transform: rotate(359deg);} -} - -@keyframes rotation { - from {transform: rotate(0deg);} - to {transform: rotate(359deg);} +@mixin wait-spinner($b: 5px, $c: $colorAlt1) { + display: block; + position: absolute; + -webkit-animation: rotation .6s infinite linear; + -moz-animation: rotation .6s infinite linear; + -o-animation: rotation .6s infinite linear; + animation: rotation .6s infinite linear; + border-color: rgba($c, 0.25); + border-top-color: rgba($c, 1.0); + border-style: solid; + border-width: $b; + @include border-radius(100%); } .t-wait-spinner, @@ -96,4 +117,28 @@ margin-top: 0 !important; padding: 0 !important; top: 0; left: 0; +} + +.loading { + // Can be applied to any block element with height and width + pointer-events: none; + &:before, + &:after { + content: ''; + } + &:before { + @include wait-spinner2(5px, $colorLoadingFg); + z-index: 10; + } + &:after { + @include absPosDefault(); + background: $colorLoadingBg; + display: block; + z-index: 9; + } + &.tree-item:before { + padding: $menuLineH / 4; + border-width: 2px; + } + } \ No newline at end of file diff --git a/platform/commonUI/general/res/sass/search/_search.scss b/platform/commonUI/general/res/sass/search/_search.scss index 3aa349d6f8..85fadc5015 100644 --- a/platform/commonUI/general/res/sass/search/_search.scss +++ b/platform/commonUI/general/res/sass/search/_search.scss @@ -214,8 +214,6 @@ .search-scroll { order: 3; - - //padding-right: $rightPadding; margin-top: 4px; // Adjustable scrolling size @@ -227,28 +225,6 @@ .load-icon { position: relative; - &.loading { - pointer-events: none; - margin-left: $leftMargin; - - .title-label { - // Text styling - font-style: italic; - font-size: .9em; - opacity: 0.5; - - // Text positioning - margin-left: $iconWidth + $leftMargin; - line-height: 24px; - } - .wait-spinner { - margin-left: $leftMargin; - } - } - - &:not(.loading) { - cursor: pointer; - } } .load-more-button { diff --git a/platform/commonUI/general/res/sass/tree/_tree.scss b/platform/commonUI/general/res/sass/tree/_tree.scss index 2c0343a6c4..d64f456b2e 100644 --- a/platform/commonUI/general/res/sass/tree/_tree.scss +++ b/platform/commonUI/general/res/sass/tree/_tree.scss @@ -83,7 +83,6 @@ ul.tree { .icon { &.l-icon-link, &.l-icon-alert { - //@include txtShdw($shdwItemTreeIcon); position: absolute; z-index: 2; } @@ -105,26 +104,12 @@ ul.tree { @include absPosDefault(); display: block; left: $runningItemW + ($interiorMargin * 3); - //right: $treeContextTriggerW + $interiorMargin; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } } - &.loading { - pointer-events: none; - .label { - opacity: 0.5; - .title-label { - font-style: italic; - } - } - .wait-spinner { - margin-left: 14px; - } - } - &.selected { background: $colorItemTreeSelectedBg; color: $colorItemTreeSelectedFg; @@ -142,9 +127,6 @@ ul.tree { &:hover { background: rgba($colorBodyFg, 0.1); //lighten($colorBodyBg, 5%); color: pullForward($colorBodyFg, 20%); - //.context-trigger { - // display: block; - //} .icon { color: $colorItemTreeIconHover; } @@ -158,7 +140,6 @@ ul.tree { .context-trigger { $h: 0.9rem; - //display: none; top: -1px; position: absolute; right: $interiorMarginSm; diff --git a/platform/commonUI/general/res/sass/user-environ/_layout.scss b/platform/commonUI/general/res/sass/user-environ/_layout.scss index bdfe716be3..0d8983c182 100644 --- a/platform/commonUI/general/res/sass/user-environ/_layout.scss +++ b/platform/commonUI/general/res/sass/user-environ/_layout.scss @@ -294,9 +294,7 @@ } &.l-controls-visible { &.l-time-controller-visible { - > ng-include { - bottom: nth($ueTimeControlH,1) + nth($ueTimeControlH,2) +nth($ueTimeControlH,3) + ($interiorMargin * 3); - } + bottom: nth($ueTimeControlH,1) + nth($ueTimeControlH,2) +nth($ueTimeControlH,3) + ($interiorMargin * 3); } } } diff --git a/platform/commonUI/general/res/templates/controls/time-controller.html b/platform/commonUI/general/res/templates/controls/time-controller.html index 7f1e8b8453..8a9be523da 100644 --- a/platform/commonUI/general/res/templates/controls/time-controller.html +++ b/platform/commonUI/general/res/templates/controls/time-controller.html @@ -19,16 +19,14 @@ this source code distribution or the Licensing information page available at runtime from the About dialog for additional information. --> - -
+
C - - +
ng-include { + /* line 296, ../../../../general/res/sass/user-environ/_layout.scss */ + .object-holder.l-controls-visible.l-time-controller-visible { bottom: 88px; } -/* line 304, ../../../../general/res/sass/user-environ/_layout.scss */ +/* line 302, ../../../../general/res/sass/user-environ/_layout.scss */ .object-browse-bar .s-btn, .object-browse-bar .s-menu-btn, .top-bar .buttons-main .s-btn, .top-bar .buttons-main .s-menu-btn, @@ -3528,12 +3609,12 @@ span.req { line-height: 25px; vertical-align: top; } -/* line 317, ../../../../general/res/sass/user-environ/_layout.scss */ +/* line 315, ../../../../general/res/sass/user-environ/_layout.scss */ .object-browse-bar .view-switcher, .top-bar .view-switcher { margin-right: 20px; } -/* line 322, ../../../../general/res/sass/user-environ/_layout.scss */ +/* line 320, ../../../../general/res/sass/user-environ/_layout.scss */ .object-browse-bar { overflow: visible; position: absolute; @@ -3549,22 +3630,22 @@ span.req { height: 24px; line-height: 24px; white-space: nowrap; } - /* line 330, ../../../../general/res/sass/user-environ/_layout.scss */ + /* line 328, ../../../../general/res/sass/user-environ/_layout.scss */ .object-browse-bar .left { padding-right: 20px; } - /* line 332, ../../../../general/res/sass/user-environ/_layout.scss */ + /* line 330, ../../../../general/res/sass/user-environ/_layout.scss */ .object-browse-bar .left .l-back { display: inline-block; float: left; margin-right: 10px; } -/* line 340, ../../../../general/res/sass/user-environ/_layout.scss */ +/* line 338, ../../../../general/res/sass/user-environ/_layout.scss */ .l-flex { display: flex; display: -webkit-flex; flex-flow: row nowrap; -webkit-flex-flow: row nowrap; } - /* line 343, ../../../../general/res/sass/user-environ/_layout.scss */ + /* line 341, ../../../../general/res/sass/user-environ/_layout.scss */ .l-flex .left { flex: 1 1 0; -webkit-flex: 1 1 0; @@ -4063,25 +4144,30 @@ span.req { position: relative; } /* line 228, ../../../../general/res/sass/search/_search.scss */ .search .search-scroll .load-icon { - position: relative; } - /* line 230, ../../../../general/res/sass/search/_search.scss */ - .search .search-scroll .load-icon.loading { - pointer-events: none; - margin-left: 6px; } - /* line 234, ../../../../general/res/sass/search/_search.scss */ - .search .search-scroll .load-icon.loading .title-label { - font-style: italic; - font-size: .9em; - opacity: 0.5; - margin-left: 26px; - line-height: 24px; } - /* line 244, ../../../../general/res/sass/search/_search.scss */ - .search .search-scroll .load-icon.loading .wait-spinner { - margin-left: 6px; } - /* line 249, ../../../../general/res/sass/search/_search.scss */ - .search .search-scroll .load-icon:not(.loading) { - cursor: pointer; } - /* line 254, ../../../../general/res/sass/search/_search.scss */ + position: relative; + /* &.loading { + pointer-events: none; + margin-left: $leftMargin; + + .title-label { + // Text styling + font-style: italic; + font-size: .9em; + opacity: 0.5; + + // Text positioning + margin-left: $iconWidth + $leftMargin; + line-height: 24px; + } + .wait-spinner { + margin-left: $leftMargin; + } + } + + &:not(.loading) { + cursor: pointer; + }*/ } + /* line 255, ../../../../general/res/sass/search/_search.scss */ .search .search-scroll .load-more-button { margin-top: 5px 0; font-size: 0.8em; @@ -4352,7 +4438,21 @@ ul.tree { height: 1.5rem; line-height: 1.5rem; margin-bottom: 3px; - position: relative; } + position: relative; + /* + &.loading { + pointer-events: none; + .label { + opacity: 0.5; + .title-label { + font-style: italic; + } + } + .wait-spinner { + margin-left: 14px; + } + } + */ } /* line 48, ../../../../general/res/sass/tree/_tree.scss */ .tree-item .view-control, .search-result-item .view-control { @@ -4435,63 +4535,47 @@ ul.tree { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } - /* line 115, ../../../../general/res/sass/tree/_tree.scss */ - .tree-item.loading, - .search-result-item.loading { - pointer-events: none; } - /* line 117, ../../../../general/res/sass/tree/_tree.scss */ - .tree-item.loading .label, - .search-result-item.loading .label { - opacity: 0.5; } - /* line 119, ../../../../general/res/sass/tree/_tree.scss */ - .tree-item.loading .label .title-label, - .search-result-item.loading .label .title-label { - font-style: italic; } - /* line 123, ../../../../general/res/sass/tree/_tree.scss */ - .tree-item.loading .wait-spinner, - .search-result-item.loading .wait-spinner { - margin-left: 14px; } - /* line 128, ../../../../general/res/sass/tree/_tree.scss */ + /* line 130, ../../../../general/res/sass/tree/_tree.scss */ .tree-item.selected, .search-result-item.selected { background: #006080; color: #cccccc; } - /* line 131, ../../../../general/res/sass/tree/_tree.scss */ + /* line 133, ../../../../general/res/sass/tree/_tree.scss */ .tree-item.selected .view-control, .search-result-item.selected .view-control { color: rgba(255, 255, 255, 0.3); } - /* line 134, ../../../../general/res/sass/tree/_tree.scss */ + /* line 136, ../../../../general/res/sass/tree/_tree.scss */ .tree-item.selected .label .type-icon, .search-result-item.selected .label .type-icon { color: #cccccc; } @media screen and (min-device-width: 800px) and (min-device-height: 1025px), screen and (min-device-width: 1025px) and (min-device-height: 800px) { - /* line 142, ../../../../general/res/sass/tree/_tree.scss */ + /* line 144, ../../../../general/res/sass/tree/_tree.scss */ .tree-item:not(.selected):hover, .search-result-item:not(.selected):hover { background: rgba(153, 153, 153, 0.1); color: #cccccc; } - /* line 148, ../../../../general/res/sass/tree/_tree.scss */ + /* line 150, ../../../../general/res/sass/tree/_tree.scss */ .tree-item:not(.selected):hover .icon, .search-result-item:not(.selected):hover .icon { color: #33ccff; } } - /* line 155, ../../../../general/res/sass/tree/_tree.scss */ + /* line 157, ../../../../general/res/sass/tree/_tree.scss */ .tree-item:not(.loading), .search-result-item:not(.loading) { cursor: pointer; } - /* line 159, ../../../../general/res/sass/tree/_tree.scss */ + /* line 161, ../../../../general/res/sass/tree/_tree.scss */ .tree-item .context-trigger, .search-result-item .context-trigger { top: -1px; position: absolute; right: 3px; } - /* line 165, ../../../../general/res/sass/tree/_tree.scss */ + /* line 167, ../../../../general/res/sass/tree/_tree.scss */ .tree-item .context-trigger .invoke-menu, .search-result-item .context-trigger .invoke-menu { font-size: 0.75em; height: 0.9rem; line-height: 0.9rem; } -/* line 174, ../../../../general/res/sass/tree/_tree.scss */ +/* line 176, ../../../../general/res/sass/tree/_tree.scss */ .tree-item .label { left: 15px; } diff --git a/platform/commonUI/themes/espresso/res/sass/_constants.scss b/platform/commonUI/themes/espresso/res/sass/_constants.scss index e6106d049c..b1851eae58 100644 --- a/platform/commonUI/themes/espresso/res/sass/_constants.scss +++ b/platform/commonUI/themes/espresso/res/sass/_constants.scss @@ -163,4 +163,8 @@ $colorCalCellSelectedFg: $colorItemTreeSelectedFg; $colorCalCellInMonthBg: pushBack($colorMenuBg, 5%); // About Screen -$colorAboutLink: #84b3ff; \ No newline at end of file +$colorAboutLink: #84b3ff; + +// Loading +$colorLoadingBg: rgba($colorBodyFg, 0.2); +$colorLoadingFg: $colorAlt1; \ No newline at end of file diff --git a/platform/commonUI/themes/snow/res/css/theme-snow.css b/platform/commonUI/themes/snow/res/css/theme-snow.css index 2650b2b90b..69af739435 100644 --- a/platform/commonUI/themes/snow/res/css/theme-snow.css +++ b/platform/commonUI/themes/snow/res/css/theme-snow.css @@ -1056,27 +1056,22 @@ mct-container { * this source code distribution or the Licensing information page available * at runtime from the About dialog for additional information. *****************************************************************************/ -@-webkit-keyframes rotation { - from { - -webkit-transform: rotate(0deg); } - to { - -webkit-transform: rotate(359deg); } } @-moz-keyframes rotation { - from { - -moz-transform: rotate(0deg); } - to { - -moz-transform: rotate(359deg); } } -@-o-keyframes rotation { - from { - -o-transform: rotate(0deg); } - to { - -o-transform: rotate(359deg); } } -@keyframes rotation { - from { + 0% { transform: rotate(0deg); } - to { + 100% { transform: rotate(359deg); } } -/* line 42, ../../../../general/res/sass/helpers/_wait-spinner.scss */ +@-webkit-keyframes rotation { + 0% { + transform: rotate(0deg); } + 100% { + transform: rotate(359deg); } } +@keyframes rotation { + 0% { + transform: rotate(0deg); } + 100% { + transform: rotate(359deg); } } +/* line 63, ../../../../general/res/sass/helpers/_wait-spinner.scss */ .t-wait-spinner, .wait-spinner { display: block; @@ -1089,6 +1084,8 @@ mct-container { border-top-color: #0099cc; border-style: solid; border-width: 0.5em; + -moz-border-radius: 100%; + -webkit-border-radius: 100%; border-radius: 100%; top: 50%; left: 50%; @@ -1099,7 +1096,7 @@ mct-container { margin-top: -5%; margin-left: -5%; z-index: 2; } - /* line 53, ../../../../general/res/sass/helpers/_wait-spinner.scss */ + /* line 74, ../../../../general/res/sass/helpers/_wait-spinner.scss */ .t-wait-spinner.inline, .wait-spinner.inline { display: inline-block !important; @@ -1107,26 +1104,26 @@ mct-container { position: relative !important; vertical-align: middle; } -/* line 61, ../../../../general/res/sass/helpers/_wait-spinner.scss */ +/* line 82, ../../../../general/res/sass/helpers/_wait-spinner.scss */ .l-wait-spinner-holder { pointer-events: none; position: absolute; } - /* line 65, ../../../../general/res/sass/helpers/_wait-spinner.scss */ + /* line 86, ../../../../general/res/sass/helpers/_wait-spinner.scss */ .l-wait-spinner-holder.align-left .t-wait-spinner { left: 0; margin-left: 0; } - /* line 70, ../../../../general/res/sass/helpers/_wait-spinner.scss */ + /* line 91, ../../../../general/res/sass/helpers/_wait-spinner.scss */ .l-wait-spinner-holder.full-size { display: inline-block; height: 100%; width: 100%; } - /* line 73, ../../../../general/res/sass/helpers/_wait-spinner.scss */ + /* line 94, ../../../../general/res/sass/helpers/_wait-spinner.scss */ .l-wait-spinner-holder.full-size .t-wait-spinner { top: 0; margin-top: 0; padding: 30%; } -/* line 82, ../../../../general/res/sass/helpers/_wait-spinner.scss */ +/* line 103, ../../../../general/res/sass/helpers/_wait-spinner.scss */ .treeview .wait-spinner { display: block; position: absolute; @@ -1138,6 +1135,8 @@ mct-container { border-top-color: #0099cc; border-style: solid; border-width: 0.25em; + -moz-border-radius: 100%; + -webkit-border-radius: 100%; border-radius: 100%; height: 10px; width: 10px; @@ -1146,7 +1145,7 @@ mct-container { top: 2px; left: 0; } -/* line 91, ../../../../general/res/sass/helpers/_wait-spinner.scss */ +/* line 112, ../../../../general/res/sass/helpers/_wait-spinner.scss */ .wait-spinner.sm { display: block; position: absolute; @@ -1158,6 +1157,8 @@ mct-container { border-top-color: #0099cc; border-style: solid; border-width: 0.25em; + -moz-border-radius: 100%; + -webkit-border-radius: 100%; border-radius: 100%; height: 13px; width: 13px; @@ -1167,6 +1168,77 @@ mct-container { top: 0; left: 0; } +/* line 122, ../../../../general/res/sass/helpers/_wait-spinner.scss */ +.loading { + pointer-events: none; } + /* line 125, ../../../../general/res/sass/helpers/_wait-spinner.scss */ + .loading:before, .loading:after { + content: ''; } + /* line 129, ../../../../general/res/sass/helpers/_wait-spinner.scss */ + .loading:before { + -moz-animation-name: rotateCentered; + -webkit-animation-name: rotateCentered; + animation-name: rotateCentered; + -moz-animation-duration: 0.5s; + -webkit-animation-duration: 0.5s; + animation-duration: 0.5s; + -moz-animation-iteration-count: infinite; + -webkit-animation-iteration-count: infinite; + animation-iteration-count: infinite; + -moz-animation-timing-function: linear; + -webkit-animation-timing-function: linear; + animation-timing-function: linear; + border-color: rgba(119, 107, 162, 0.25); + border-top-color: #776ba2; + border-style: solid; + border-width: 5px; + -moz-border-radius: 100%; + -webkit-border-radius: 100%; + border-radius: 100%; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + display: block; + position: absolute; + height: 0; + width: 0; + padding: 7%; + left: 50%; + top: 50%; + z-index: 10; } +@-moz-keyframes rotateCentered { + 0% { + transform: translateX(-50%) translateY(-50%) rotate(0deg); } + 100% { + transform: translateX(-50%) translateY(-50%) rotate(359deg); } } +@-webkit-keyframes rotateCentered { + 0% { + transform: translateX(-50%) translateY(-50%) rotate(0deg); } + 100% { + transform: translateX(-50%) translateY(-50%) rotate(359deg); } } +@keyframes rotateCentered { + 0% { + transform: translateX(-50%) translateY(-50%) rotate(0deg); } + 100% { + transform: translateX(-50%) translateY(-50%) rotate(359deg); } } + /* line 133, ../../../../general/res/sass/helpers/_wait-spinner.scss */ + .loading:after { + overflow: hidden; + position: absolute; + top: 0px; + right: 0px; + bottom: 0px; + left: 0px; + width: auto; + height: auto; + background: rgba(119, 107, 162, 0.1); + display: block; + z-index: 9; } + /* line 139, ../../../../general/res/sass/helpers/_wait-spinner.scss */ + .loading.tree-item:before { + padding: 0.375rem; + border-width: 2px; } + /* Styles for messages */ /* line 4, ../../../../general/res/sass/_messages.scss */ .message.block { @@ -1908,7 +1980,6 @@ label.checkbox.custom { width: 230px; } /* line 356, ../../../../general/res/sass/controls/_controls.scss */ .l-datetime-picker .l-month-year-pager { - font-size: 0.8rem; height: 15px; margin-bottom: 5px; position: relative; } @@ -2342,206 +2413,216 @@ label.checkbox.custom { right: 0; width: auto; } -/* line 27, ../../../../general/res/sass/controls/_time-controller.scss */ -.l-time-controller .l-time-range-inputs-holder, -.l-time-controller .l-time-range-slider { - font-size: 0.8em; } -/* line 32, ../../../../general/res/sass/controls/_time-controller.scss */ -.l-time-controller .l-time-range-inputs-holder, -.l-time-controller .l-time-range-slider-holder, -.l-time-controller .l-time-range-ticks-holder { - overflow: visible; +/* line 13, ../../../../general/res/sass/controls/_time-controller.scss */ +mct-include.l-time-controller { + overflow: hidden; position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; + top: 0px; + right: 0px; + bottom: 0px; + left: 0px; width: auto; height: auto; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; - min-width: 400px; - top: auto; } -/* line 42, ../../../../general/res/sass/controls/_time-controller.scss */ -.l-time-controller .l-time-range-slider, -.l-time-controller .l-time-range-ticks { - overflow: visible; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - width: auto; - height: auto; - left: 150px; - right: 150px; } -/* line 49, ../../../../general/res/sass/controls/_time-controller.scss */ -.l-time-controller .l-time-range-inputs-holder { - height: 33px; - bottom: 46px; - padding-top: 5px; - border-top: 1px solid rgba(102, 102, 102, 0.2); } - /* line 54, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .l-time-range-inputs-holder .type-icon { - font-size: 120%; - vertical-align: middle; } - /* line 58, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .l-time-range-inputs-holder .l-time-range-input, - .l-time-controller .l-time-range-inputs-holder .l-time-range-inputs-elem { - margin-right: 5px; } - /* line 61, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .l-time-range-inputs-holder .l-time-range-input .lbl, - .l-time-controller .l-time-range-inputs-holder .l-time-range-inputs-elem .lbl { - color: #999999; } - /* line 64, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .l-time-range-inputs-holder .l-time-range-input .ui-symbol.icon, .l-time-controller .l-time-range-inputs-holder .l-time-range-input .l-datetime-picker .l-month-year-pager .icon.pager, .l-datetime-picker .l-month-year-pager .l-time-controller .l-time-range-inputs-holder .l-time-range-input .icon.pager, - .l-time-controller .l-time-range-inputs-holder .l-time-range-inputs-elem .ui-symbol.icon, - .l-time-controller .l-time-range-inputs-holder .l-time-range-inputs-elem .l-datetime-picker .l-month-year-pager .icon.pager, - .l-datetime-picker .l-month-year-pager .l-time-controller .l-time-range-inputs-holder .l-time-range-inputs-elem .icon.pager { - font-size: 11px; - width: 11px; } -/* line 71, ../../../../general/res/sass/controls/_time-controller.scss */ -.l-time-controller .l-time-range-slider-holder { - height: 20px; - bottom: 23px; } - /* line 74, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .l-time-range-slider-holder .range-holder { - -moz-box-shadow: none; - -webkit-box-shadow: none; - box-shadow: none; - background: none; - border: none; } - /* line 79, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .l-time-range-slider-holder .range-holder .range .toi-line { - -moz-transform: translateX(50%); - -ms-transform: translateX(50%); - -webkit-transform: translateX(50%); - transform: translateX(50%); - position: absolute; - top: 0; - right: 0; - bottom: 0px; - left: auto; - width: 8px; - height: auto; - z-index: 2; } - /* line 89, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .l-time-range-slider-holder .range-holder .range .toi-line:before, .l-time-controller .l-time-range-slider-holder .range-holder .range .toi-line:after { - background-color: #666; - content: ""; - position: absolute; } - /* line 95, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .l-time-range-slider-holder .range-holder .range .toi-line:before { - top: 0; - right: auto; - bottom: -10px; - left: 3px; - width: 2px; } - /* line 101, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .l-time-range-slider-holder .range-holder .range .toi-line:after { - -moz-border-radius: 8px; - -webkit-border-radius: 8px; - border-radius: 8px; - -moz-transform: translateY(-50%); - -ms-transform: translateY(-50%); - -webkit-transform: translateY(-50%); - transform: translateY(-50%); - top: 50%; - right: 0; - bottom: auto; - left: 0; - width: auto; - height: 8px; } - /* line 3, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .l-time-range-slider-holder .range-holder .range:hover .toi-line:before, .l-time-controller .l-time-range-slider-holder .range-holder .range:hover .toi-line:after { - background-color: #0052b5; } - /* line 117, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .l-time-range-slider-holder:not(:active) .knob, - .l-time-controller .l-time-range-slider-holder:not(:active) .range { - -moz-transition-property: left, right; - -o-transition-property: left, right; - -webkit-transition-property: left, right; - transition-property: left, right; - -moz-transition-duration: 500ms; - -o-transition-duration: 500ms; - -webkit-transition-duration: 500ms; - transition-duration: 500ms; - -moz-transition-timing-function: ease-in-out; - -o-transition-timing-function: ease-in-out; - -webkit-transition-timing-function: ease-in-out; - transition-timing-function: ease-in-out; } -/* line 126, ../../../../general/res/sass/controls/_time-controller.scss */ -.l-time-controller .l-time-range-ticks-holder { - height: 20px; } - /* line 128, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .l-time-range-ticks-holder .l-time-range-ticks { - border-top: 1px solid rgba(0, 0, 0, 0.2); } - /* line 130, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .l-time-range-ticks-holder .l-time-range-ticks .tick { - background-color: rgba(0, 0, 0, 0.2); - border: none; - height: 5px; - width: 1px; - margin-left: -1px; - position: absolute; } - /* line 137, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .l-time-range-ticks-holder .l-time-range-ticks .tick:first-child { - margin-left: 0; } - /* line 140, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .l-time-range-ticks-holder .l-time-range-ticks .tick .l-time-range-tick-label { - transform: translateX(-50%); - -webkit-transform: translateX(-50%); - color: #999999; - display: inline-block; - font-size: 0.7em; - position: absolute; - top: 8px; - white-space: nowrap; - z-index: 2; } -/* line 154, ../../../../general/res/sass/controls/_time-controller.scss */ -.l-time-controller .knob { - z-index: 2; } - /* line 156, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .knob .range-value { - -moz-transition-property: visibility, opacity, background-color, border-color; - -o-transition-property: visibility, opacity, background-color, border-color; - -webkit-transition-property: visibility, opacity, background-color, border-color; - transition-property: visibility, opacity, background-color, border-color; - -moz-transition-duration: 0.25s; - -o-transition-duration: 0.25s; - -webkit-transition-duration: 0.25s; - transition-duration: 0.25s; - -moz-transition-timing-function: ease-in-out; - -o-transition-timing-function: ease-in-out; - -webkit-transition-timing-function: ease-in-out; - transition-timing-function: ease-in-out; - padding: 0 10px; + display: block; + top: auto; + height: 83px; + min-width: 500px; + font-size: 0.8rem; } + /* line 38, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .l-time-range-inputs-holder, + mct-include.l-time-controller .l-time-range-slider-holder, + mct-include.l-time-controller .l-time-range-ticks-holder { + overflow: visible; position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: auto; + height: auto; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + top: auto; } + /* line 47, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .l-time-range-slider, + mct-include.l-time-controller .l-time-range-ticks { + overflow: visible; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: auto; + height: auto; + left: 150px; + right: 150px; } + /* line 54, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .l-time-range-inputs-holder { + height: 33px; + bottom: 46px; + padding-top: 5px; + border-top: 1px solid rgba(102, 102, 102, 0.2); } + /* line 59, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .l-time-range-inputs-holder .type-icon { + font-size: 120%; + vertical-align: middle; } + /* line 63, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .l-time-range-inputs-holder .l-time-range-input, + mct-include.l-time-controller .l-time-range-inputs-holder .l-time-range-inputs-elem { + margin-right: 5px; } + /* line 66, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .l-time-range-inputs-holder .l-time-range-input .lbl, + mct-include.l-time-controller .l-time-range-inputs-holder .l-time-range-inputs-elem .lbl { + color: #999999; } + /* line 69, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .l-time-range-inputs-holder .l-time-range-input .ui-symbol.icon, mct-include.l-time-controller .l-time-range-inputs-holder .l-time-range-input .l-datetime-picker .l-month-year-pager .icon.pager, .l-datetime-picker .l-month-year-pager mct-include.l-time-controller .l-time-range-inputs-holder .l-time-range-input .icon.pager, + mct-include.l-time-controller .l-time-range-inputs-holder .l-time-range-inputs-elem .ui-symbol.icon, + mct-include.l-time-controller .l-time-range-inputs-holder .l-time-range-inputs-elem .l-datetime-picker .l-month-year-pager .icon.pager, + .l-datetime-picker .l-month-year-pager mct-include.l-time-controller .l-time-range-inputs-holder .l-time-range-inputs-elem .icon.pager { + font-size: 11px; + width: 11px; } + /* line 76, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .l-time-range-slider-holder { height: 20px; - line-height: 20px; - white-space: nowrap; } - /* line 165, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .knob:hover .range-value { - color: rgba(0, 153, 204, 0.7); } - /* line 168, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .knob.knob-l { - margin-left: -10px; } - /* line 171, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .knob.knob-l .range-value { - text-align: right; - right: 10px; } - /* line 176, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .knob.knob-r { - margin-right: -10px; } - /* line 179, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .knob.knob-r .range-value { - left: 10px; } - /* line 3, ../../../../general/res/sass/controls/_time-controller.scss */ - .l-time-controller .knob.knob-r:hover + .range-holder .range .toi-line:before, .l-time-controller .knob.knob-r:hover + .range-holder .range .toi-line:after { - background-color: #0052b5; } + bottom: 23px; } + /* line 79, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .l-time-range-slider-holder .range-holder { + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; + background: none; + border: none; } + /* line 84, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .l-time-range-slider-holder .range-holder .range .toi-line { + -moz-transform: translateX(50%); + -ms-transform: translateX(50%); + -webkit-transform: translateX(50%); + transform: translateX(50%); + position: absolute; + top: 0; + right: 0; + bottom: 0px; + left: auto; + width: 8px; + height: auto; + z-index: 2; } + /* line 94, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .l-time-range-slider-holder .range-holder .range .toi-line:before, mct-include.l-time-controller .l-time-range-slider-holder .range-holder .range .toi-line:after { + background-color: #666; + content: ""; + position: absolute; } + /* line 100, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .l-time-range-slider-holder .range-holder .range .toi-line:before { + top: 0; + right: auto; + bottom: -10px; + left: 3px; + width: 2px; } + /* line 106, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .l-time-range-slider-holder .range-holder .range .toi-line:after { + -moz-border-radius: 8px; + -webkit-border-radius: 8px; + border-radius: 8px; + -moz-transform: translateY(-50%); + -ms-transform: translateY(-50%); + -webkit-transform: translateY(-50%); + transform: translateY(-50%); + top: 50%; + right: 0; + bottom: auto; + left: 0; + width: auto; + height: 8px; } + /* line 3, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .l-time-range-slider-holder .range-holder .range:hover .toi-line:before, mct-include.l-time-controller .l-time-range-slider-holder .range-holder .range:hover .toi-line:after { + background-color: #0052b5; } + /* line 122, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .l-time-range-slider-holder:not(:active) .knob, + mct-include.l-time-controller .l-time-range-slider-holder:not(:active) .range { + -moz-transition-property: left, right; + -o-transition-property: left, right; + -webkit-transition-property: left, right; + transition-property: left, right; + -moz-transition-duration: 500ms; + -o-transition-duration: 500ms; + -webkit-transition-duration: 500ms; + transition-duration: 500ms; + -moz-transition-timing-function: ease-in-out; + -o-transition-timing-function: ease-in-out; + -webkit-transition-timing-function: ease-in-out; + transition-timing-function: ease-in-out; } + /* line 131, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .l-time-range-ticks-holder { + height: 20px; } + /* line 133, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .l-time-range-ticks-holder .l-time-range-ticks { + border-top: 1px solid rgba(0, 0, 0, 0.2); } + /* line 135, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .l-time-range-ticks-holder .l-time-range-ticks .tick { + background-color: rgba(0, 0, 0, 0.2); + border: none; + height: 5px; + width: 1px; + margin-left: -1px; + position: absolute; } + /* line 142, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .l-time-range-ticks-holder .l-time-range-ticks .tick:first-child { + margin-left: 0; } + /* line 145, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .l-time-range-ticks-holder .l-time-range-ticks .tick .l-time-range-tick-label { + transform: translateX(-50%); + -webkit-transform: translateX(-50%); + color: #999999; + display: inline-block; + font-size: 0.9em; + position: absolute; + top: 8px; + white-space: nowrap; + z-index: 2; } + /* line 159, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .knob { + z-index: 2; } + /* line 161, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .knob .range-value { + -moz-transition-property: visibility, opacity, background-color, border-color; + -o-transition-property: visibility, opacity, background-color, border-color; + -webkit-transition-property: visibility, opacity, background-color, border-color; + transition-property: visibility, opacity, background-color, border-color; + -moz-transition-duration: 0.25s; + -o-transition-duration: 0.25s; + -webkit-transition-duration: 0.25s; + transition-duration: 0.25s; + -moz-transition-timing-function: ease-in-out; + -o-transition-timing-function: ease-in-out; + -webkit-transition-timing-function: ease-in-out; + transition-timing-function: ease-in-out; + padding: 0 10px; + position: absolute; + height: 20px; + line-height: 20px; + white-space: nowrap; } + /* line 170, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .knob:hover .range-value { + color: rgba(0, 153, 204, 0.7); } + /* line 173, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .knob.knob-l { + margin-left: -10px; } + /* line 176, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .knob.knob-l .range-value { + text-align: right; + right: 10px; } + /* line 181, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .knob.knob-r { + margin-right: -10px; } + /* line 184, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .knob.knob-r .range-value { + left: 10px; } + /* line 3, ../../../../general/res/sass/controls/_time-controller.scss */ + mct-include.l-time-controller .knob.knob-r:hover + .range-holder .range .toi-line:before, mct-include.l-time-controller .knob.knob-r:hover + .range-holder .range .toi-line:after { + background-color: #0052b5; } -/* line 193, ../../../../general/res/sass/controls/_time-controller.scss */ +/* line 198, ../../../../general/res/sass/controls/_time-controller.scss */ .s-time-range-val { -moz-border-radius: 4px; -webkit-border-radius: 4px; @@ -3459,11 +3540,11 @@ span.req { left: 0; width: auto; height: auto; } - /* line 297, ../../../../general/res/sass/user-environ/_layout.scss */ - .object-holder.l-controls-visible.l-time-controller-visible > ng-include { + /* line 296, ../../../../general/res/sass/user-environ/_layout.scss */ + .object-holder.l-controls-visible.l-time-controller-visible { bottom: 88px; } -/* line 304, ../../../../general/res/sass/user-environ/_layout.scss */ +/* line 302, ../../../../general/res/sass/user-environ/_layout.scss */ .object-browse-bar .s-btn, .object-browse-bar .s-menu-btn, .top-bar .buttons-main .s-btn, .top-bar .buttons-main .s-menu-btn, @@ -3475,12 +3556,12 @@ span.req { line-height: 25px; vertical-align: top; } -/* line 317, ../../../../general/res/sass/user-environ/_layout.scss */ +/* line 315, ../../../../general/res/sass/user-environ/_layout.scss */ .object-browse-bar .view-switcher, .top-bar .view-switcher { margin-right: 20px; } -/* line 322, ../../../../general/res/sass/user-environ/_layout.scss */ +/* line 320, ../../../../general/res/sass/user-environ/_layout.scss */ .object-browse-bar { overflow: visible; position: absolute; @@ -3496,22 +3577,22 @@ span.req { height: 24px; line-height: 24px; white-space: nowrap; } - /* line 330, ../../../../general/res/sass/user-environ/_layout.scss */ + /* line 328, ../../../../general/res/sass/user-environ/_layout.scss */ .object-browse-bar .left { padding-right: 20px; } - /* line 332, ../../../../general/res/sass/user-environ/_layout.scss */ + /* line 330, ../../../../general/res/sass/user-environ/_layout.scss */ .object-browse-bar .left .l-back { display: inline-block; float: left; margin-right: 10px; } -/* line 340, ../../../../general/res/sass/user-environ/_layout.scss */ +/* line 338, ../../../../general/res/sass/user-environ/_layout.scss */ .l-flex { display: flex; display: -webkit-flex; flex-flow: row nowrap; -webkit-flex-flow: row nowrap; } - /* line 343, ../../../../general/res/sass/user-environ/_layout.scss */ + /* line 341, ../../../../general/res/sass/user-environ/_layout.scss */ .l-flex .left { flex: 1 1 0; -webkit-flex: 1 1 0; @@ -4010,25 +4091,30 @@ span.req { position: relative; } /* line 228, ../../../../general/res/sass/search/_search.scss */ .search .search-scroll .load-icon { - position: relative; } - /* line 230, ../../../../general/res/sass/search/_search.scss */ - .search .search-scroll .load-icon.loading { - pointer-events: none; - margin-left: 6px; } - /* line 234, ../../../../general/res/sass/search/_search.scss */ - .search .search-scroll .load-icon.loading .title-label { - font-style: italic; - font-size: .9em; - opacity: 0.5; - margin-left: 26px; - line-height: 24px; } - /* line 244, ../../../../general/res/sass/search/_search.scss */ - .search .search-scroll .load-icon.loading .wait-spinner { - margin-left: 6px; } - /* line 249, ../../../../general/res/sass/search/_search.scss */ - .search .search-scroll .load-icon:not(.loading) { - cursor: pointer; } - /* line 254, ../../../../general/res/sass/search/_search.scss */ + position: relative; + /* &.loading { + pointer-events: none; + margin-left: $leftMargin; + + .title-label { + // Text styling + font-style: italic; + font-size: .9em; + opacity: 0.5; + + // Text positioning + margin-left: $iconWidth + $leftMargin; + line-height: 24px; + } + .wait-spinner { + margin-left: $leftMargin; + } + } + + &:not(.loading) { + cursor: pointer; + }*/ } + /* line 255, ../../../../general/res/sass/search/_search.scss */ .search .search-scroll .load-more-button { margin-top: 5px 0; font-size: 0.8em; @@ -4281,7 +4367,21 @@ ul.tree { height: 1.5rem; line-height: 1.5rem; margin-bottom: 3px; - position: relative; } + position: relative; + /* + &.loading { + pointer-events: none; + .label { + opacity: 0.5; + .title-label { + font-style: italic; + } + } + .wait-spinner { + margin-left: 14px; + } + } + */ } /* line 48, ../../../../general/res/sass/tree/_tree.scss */ .tree-item .view-control, .search-result-item .view-control { @@ -4363,63 +4463,47 @@ ul.tree { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } - /* line 115, ../../../../general/res/sass/tree/_tree.scss */ - .tree-item.loading, - .search-result-item.loading { - pointer-events: none; } - /* line 117, ../../../../general/res/sass/tree/_tree.scss */ - .tree-item.loading .label, - .search-result-item.loading .label { - opacity: 0.5; } - /* line 119, ../../../../general/res/sass/tree/_tree.scss */ - .tree-item.loading .label .title-label, - .search-result-item.loading .label .title-label { - font-style: italic; } - /* line 123, ../../../../general/res/sass/tree/_tree.scss */ - .tree-item.loading .wait-spinner, - .search-result-item.loading .wait-spinner { - margin-left: 14px; } - /* line 128, ../../../../general/res/sass/tree/_tree.scss */ + /* line 130, ../../../../general/res/sass/tree/_tree.scss */ .tree-item.selected, .search-result-item.selected { background: #1ac6ff; color: #fcfcfc; } - /* line 131, ../../../../general/res/sass/tree/_tree.scss */ + /* line 133, ../../../../general/res/sass/tree/_tree.scss */ .tree-item.selected .view-control, .search-result-item.selected .view-control { color: #fcfcfc; } - /* line 134, ../../../../general/res/sass/tree/_tree.scss */ + /* line 136, ../../../../general/res/sass/tree/_tree.scss */ .tree-item.selected .label .type-icon, .search-result-item.selected .label .type-icon { color: #fcfcfc; } @media screen and (min-device-width: 800px) and (min-device-height: 1025px), screen and (min-device-width: 1025px) and (min-device-height: 800px) { - /* line 142, ../../../../general/res/sass/tree/_tree.scss */ + /* line 144, ../../../../general/res/sass/tree/_tree.scss */ .tree-item:not(.selected):hover, .search-result-item:not(.selected):hover { background: rgba(102, 102, 102, 0.1); color: #333333; } - /* line 148, ../../../../general/res/sass/tree/_tree.scss */ + /* line 150, ../../../../general/res/sass/tree/_tree.scss */ .tree-item:not(.selected):hover .icon, .search-result-item:not(.selected):hover .icon { color: #0099cc; } } - /* line 155, ../../../../general/res/sass/tree/_tree.scss */ + /* line 157, ../../../../general/res/sass/tree/_tree.scss */ .tree-item:not(.loading), .search-result-item:not(.loading) { cursor: pointer; } - /* line 159, ../../../../general/res/sass/tree/_tree.scss */ + /* line 161, ../../../../general/res/sass/tree/_tree.scss */ .tree-item .context-trigger, .search-result-item .context-trigger { top: -1px; position: absolute; right: 3px; } - /* line 165, ../../../../general/res/sass/tree/_tree.scss */ + /* line 167, ../../../../general/res/sass/tree/_tree.scss */ .tree-item .context-trigger .invoke-menu, .search-result-item .context-trigger .invoke-menu { font-size: 0.75em; height: 0.9rem; line-height: 0.9rem; } -/* line 174, ../../../../general/res/sass/tree/_tree.scss */ +/* line 176, ../../../../general/res/sass/tree/_tree.scss */ .tree-item .label { left: 15px; } diff --git a/platform/commonUI/themes/snow/res/sass/_constants.scss b/platform/commonUI/themes/snow/res/sass/_constants.scss index e24d0d8b5a..f97f2a4df0 100644 --- a/platform/commonUI/themes/snow/res/sass/_constants.scss +++ b/platform/commonUI/themes/snow/res/sass/_constants.scss @@ -36,7 +36,7 @@ $timeControllerToiLineColor: $colorBodyFg; $timeControllerToiLineColorHov: #0052b5; // General Colors -$colorAlt1: #ff6600; +$colorAlt1: #776ba2; $colorAlert: #ff3c00; $colorIconLink: #49dedb; $colorPausedBg: #ff9900; @@ -161,4 +161,8 @@ $colorCalCellSelectedFg: $colorItemTreeSelectedFg; $colorCalCellInMonthBg: pullForward($colorMenuBg, 5%); // About Screen -$colorAboutLink: #84b3ff; \ No newline at end of file +$colorAboutLink: #84b3ff; + +// Loading +$colorLoadingFg: $colorAlt1; +$colorLoadingBg: rgba($colorLoadingFg, 0.1); \ No newline at end of file diff --git a/platform/features/conductor/bundle.json b/platform/features/conductor/bundle.json index 2e4a7c652f..de903cfb93 100644 --- a/platform/features/conductor/bundle.json +++ b/platform/features/conductor/bundle.json @@ -23,7 +23,23 @@ { "key": "conductorService", "implementation": "ConductorService.js", - "depends": [ "now" ] + "depends": [ "now", "TIME_CONDUCTOR_DOMAINS" ] + } + ], + "templates": [ + { + "key": "time-conductor", + "templateUrl": "templates/time-conductor.html" + } + ], + "constants": [ + { + "key": "TIME_CONDUCTOR_DOMAINS", + "value": [ + { "key": "time", "name": "Time" }, + { "key": "yesterday", "name": "Yesterday" } + ], + "comment": "Placeholder; to be replaced by inspection of available domains." } ] } diff --git a/platform/features/conductor/res/templates/time-conductor.html b/platform/features/conductor/res/templates/time-conductor.html new file mode 100644 index 0000000000..4126652d5b --- /dev/null +++ b/platform/features/conductor/res/templates/time-conductor.html @@ -0,0 +1,10 @@ + + + + diff --git a/platform/features/conductor/src/ConductorRepresenter.js b/platform/features/conductor/src/ConductorRepresenter.js index 9f9c6a291f..0d9314ed2d 100644 --- a/platform/features/conductor/src/ConductorRepresenter.js +++ b/platform/features/conductor/src/ConductorRepresenter.js @@ -26,9 +26,8 @@ define( function () { "use strict"; - var CONDUCTOR_HEIGHT = "100px", - TEMPLATE = [ - "", + var TEMPLATE = [ + "", "" ].join(''), THROTTLE_MS = 200, @@ -78,7 +77,8 @@ define( function bounds(start, end) { return { start: conductor.displayStart(), - end: conductor.displayEnd() + end: conductor.displayEnd(), + domain: conductor.domain() }; } @@ -89,12 +89,30 @@ define( } function updateConductorInner() { - conductor.displayStart(conductorScope.conductor.inner.start); - conductor.displayEnd(conductorScope.conductor.inner.end); + var innerBounds = conductorScope.ngModel.conductor.inner; + conductor.displayStart(innerBounds.start); + conductor.displayEnd(innerBounds.end); lastObservedBounds = lastObservedBounds || bounds(); broadcastBounds(); } + function updateDomain(value) { + conductor.domain(value); + repScope.$broadcast('telemetry:display:bounds', bounds( + conductor.displayStart(), + conductor.displayEnd(), + conductor.domain() + )); + } + + // telemetry domain metadata -> option for a select control + function makeOption(domainOption) { + return { + name: domainOption.name, + value: domainOption.key + }; + } + broadcastBounds = this.throttle(function () { var newlyObservedBounds = bounds(); @@ -107,12 +125,19 @@ define( } }, THROTTLE_MS); - conductorScope.conductor = { outer: bounds(), inner: bounds() }; + conductorScope.ngModel = {}; + conductorScope.ngModel.conductor = + { outer: bounds(), inner: bounds() }; + conductorScope.ngModel.options = + conductor.domainOptions().map(makeOption); + conductorScope.ngModel.domain = conductor.domain(); conductorScope - .$watch('conductor.inner.start', updateConductorInner); + .$watch('ngModel.conductor.inner.start', updateConductorInner); conductorScope - .$watch('conductor.inner.end', updateConductorInner); + .$watch('ngModel.conductor.inner.end', updateConductorInner); + conductorScope + .$watch('ngModel.domain', updateDomain); repScope.$on('telemetry:view', updateConductorInner); }; diff --git a/platform/features/conductor/src/ConductorService.js b/platform/features/conductor/src/ConductorService.js index 59cfa95e3c..3e281d2c1d 100644 --- a/platform/features/conductor/src/ConductorService.js +++ b/platform/features/conductor/src/ConductorService.js @@ -39,12 +39,15 @@ define( * @param {Function} now a function which returns the current time * as a UNIX timestamp, in milliseconds */ - function ConductorService(now) { + function ConductorService(now, domains) { var initialEnd = Math.ceil(now() / SIX_HOURS_IN_MS) * SIX_HOURS_IN_MS; - this.conductor = - new TimeConductor(initialEnd - ONE_DAY_IN_MS, initialEnd); + this.conductor = new TimeConductor( + initialEnd - ONE_DAY_IN_MS, + initialEnd, + domains + ); } /** diff --git a/platform/features/conductor/src/ConductorTelemetryDecorator.js b/platform/features/conductor/src/ConductorTelemetryDecorator.js index ed16db7d1b..ab2d958d7e 100644 --- a/platform/features/conductor/src/ConductorTelemetryDecorator.js +++ b/platform/features/conductor/src/ConductorTelemetryDecorator.js @@ -44,12 +44,14 @@ define( ConductorTelemetryDecorator.prototype.amendRequests = function (requests) { var conductor = this.conductorService.getConductor(), start = conductor.displayStart(), - end = conductor.displayEnd(); + end = conductor.displayEnd(), + domain = conductor.domain(); function amendRequest(request) { request = request || {}; request.start = start; request.end = end; + request.domain = domain; return request; } diff --git a/platform/features/conductor/src/TimeConductor.js b/platform/features/conductor/src/TimeConductor.js index 394d9b01bb..0fa0403fd9 100644 --- a/platform/features/conductor/src/TimeConductor.js +++ b/platform/features/conductor/src/TimeConductor.js @@ -40,8 +40,10 @@ define( * @param {number} start the initial start time * @param {number} end the initial end time */ - function TimeConductor(start, end) { + function TimeConductor(start, end, domains) { this.range = { start: start, end: end }; + this.domains = domains; + this.activeDomain = domains[0].key; } /** @@ -68,6 +70,34 @@ define( return this.range.end; }; + /** + * Get available domain options which can be used to bound time + * selection. + * @returns {TelemetryDomain[]} available domains + */ + TimeConductor.prototype.domainOptions = function () { + return this.domains; + }; + + /** + * Get or set (if called with an argument) the active domain. + * @param {string} [key] the key identifying the domain choice + * @returns {TelemetryDomain} the active telemetry domain + */ + TimeConductor.prototype.domain = function (key) { + function matchesKey(domain) { + return domain.key === key; + } + + if (arguments.length > 0) { + if (!this.domains.some(matchesKey)) { + throw new Error("Unknown domain " + key); + } + this.activeDomain = key; + } + return this.activeDomain; + }; + return TimeConductor; } ); diff --git a/platform/features/conductor/test/ConductorRepresenterSpec.js b/platform/features/conductor/test/ConductorRepresenterSpec.js index 59fae1b4ee..5d78c8a720 100644 --- a/platform/features/conductor/test/ConductorRepresenterSpec.js +++ b/platform/features/conductor/test/ConductorRepresenterSpec.js @@ -21,12 +21,9 @@ *****************************************************************************/ /*global define,describe,it,expect,beforeEach,waitsFor,afterEach,jasmine*/ -/** - * EventSpec. Created by vwoeltje on 11/6/14. Modified by shale on 06/23/2015. - */ define( - ["../src/ConductorRepresenter"], - function (ConductorRepresenter) { + ["../src/ConductorRepresenter", "./TestTimeConductor"], + function (ConductorRepresenter, TestTimeConductor) { "use strict"; var SCOPE_METHODS = [ @@ -77,10 +74,7 @@ define( testViews = [ { someKey: "some value" } ]; mockScope = jasmine.createSpyObj('scope', SCOPE_METHODS); mockElement = jasmine.createSpyObj('element', ELEMENT_METHODS); - mockConductor = jasmine.createSpyObj( - 'conductor', - [ 'displayStart', 'displayEnd' ] - ); + mockConductor = new TestTimeConductor(); mockCompiledTemplate = jasmine.createSpy('template'); mockNewScope = jasmine.createSpyObj('newScope', SCOPE_METHODS); mockNewElement = jasmine.createSpyObj('newElement', ELEMENT_METHODS); @@ -135,11 +129,12 @@ define( it("exposes conductor state in scope", function () { mockConductor.displayStart.andReturn(1977); mockConductor.displayEnd.andReturn(1984); + mockConductor.domain.andReturn('d'); representer.represent(testViews[0], {}); - expect(mockNewScope.conductor).toEqual({ - inner: { start: 1977, end: 1984 }, - outer: { start: 1977, end: 1984 } + expect(mockNewScope.ngModel.conductor).toEqual({ + inner: { start: 1977, end: 1984, domain: 'd' }, + outer: { start: 1977, end: 1984, domain: 'd' } }); }); @@ -151,17 +146,27 @@ define( representer.represent(testViews[0], {}); - mockNewScope.conductor = testState; + mockNewScope.ngModel.conductor = testState; - fireWatch(mockNewScope, 'conductor.inner.start', testState.inner.start); + fireWatch( + mockNewScope, + 'ngModel.conductor.inner.start', + testState.inner.start + ); expect(mockConductor.displayStart).toHaveBeenCalledWith(42); - fireWatch(mockNewScope, 'conductor.inner.end', testState.inner.end); + fireWatch( + mockNewScope, + 'ngModel.conductor.inner.end', + testState.inner.end + ); expect(mockConductor.displayEnd).toHaveBeenCalledWith(1984); }); describe("when bounds are changing", function () { - var mockThrottledFn = jasmine.createSpy('throttledFn'), + var startWatch = "ngModel.conductor.inner.start", + endWatch = "ngModel.conductor.inner.end", + mockThrottledFn = jasmine.createSpy('throttledFn'), testBounds; function fireThrottledFn() { @@ -172,7 +177,7 @@ define( mockThrottle.andReturn(mockThrottledFn); representer.represent(testViews[0], {}); testBounds = { start: 0, end: 1000 }; - mockNewScope.conductor.inner = testBounds; + mockNewScope.ngModel.conductor.inner = testBounds; mockConductor.displayStart.andCallFake(function () { return testBounds.start; }); @@ -184,14 +189,14 @@ define( it("does not broadcast while bounds are changing", function () { expect(mockScope.$broadcast).not.toHaveBeenCalled(); testBounds.start = 100; - fireWatch(mockNewScope, 'conductor.inner.start', testBounds.start); + fireWatch(mockNewScope, startWatch, testBounds.start); testBounds.end = 500; - fireWatch(mockNewScope, 'conductor.inner.end', testBounds.end); + fireWatch(mockNewScope, endWatch, testBounds.end); fireThrottledFn(); testBounds.start = 200; - fireWatch(mockNewScope, 'conductor.inner.start', testBounds.start); + fireWatch(mockNewScope, startWatch, testBounds.start); testBounds.end = 400; - fireWatch(mockNewScope, 'conductor.inner.end', testBounds.end); + fireWatch(mockNewScope, endWatch, testBounds.end); fireThrottledFn(); expect(mockScope.$broadcast).not.toHaveBeenCalled(); }); @@ -199,17 +204,56 @@ define( it("does broadcast when bounds have stabilized", function () { expect(mockScope.$broadcast).not.toHaveBeenCalled(); testBounds.start = 100; - fireWatch(mockNewScope, 'conductor.inner.start', testBounds.start); + fireWatch(mockNewScope, startWatch, testBounds.start); testBounds.end = 500; - fireWatch(mockNewScope, 'conductor.inner.end', testBounds.end); + fireWatch(mockNewScope, endWatch, testBounds.end); fireThrottledFn(); - fireWatch(mockNewScope, 'conductor.inner.start', testBounds.start); - fireWatch(mockNewScope, 'conductor.inner.end', testBounds.end); + fireWatch(mockNewScope, startWatch, testBounds.start); + fireWatch(mockNewScope, endWatch, testBounds.end); fireThrottledFn(); expect(mockScope.$broadcast).toHaveBeenCalled(); }); }); + it("exposes domain selection in scope", function () { + representer.represent(testViews[0], null); + + expect(mockNewScope.ngModel.domain) + .toEqual(mockConductor.domain()); + }); + + it("exposes domain options in scope", function () { + representer.represent(testViews[0], null); + + mockConductor.domainOptions().forEach(function (option, i) { + expect(mockNewScope.ngModel.options[i].value) + .toEqual(option.key); + expect(mockNewScope.ngModel.options[i].name) + .toEqual(option.name); + }); + }); + + it("updates domain selection from scope", function () { + var choice; + representer.represent(testViews[0], null); + + // Choose a domain that isn't currently selected + mockNewScope.ngModel.options.forEach(function (option) { + if (option.value !== mockNewScope.ngModel.domain) { + choice = option.value; + } + }); + + expect(mockConductor.domain) + .not.toHaveBeenCalledWith(choice); + + mockNewScope.ngModel.domain = choice; + fireWatch(mockNewScope, "ngModel.domain", choice); + + expect(mockConductor.domain) + .toHaveBeenCalledWith(choice); + }); + }); } ); diff --git a/platform/features/conductor/test/ConductorServiceSpec.js b/platform/features/conductor/test/ConductorServiceSpec.js index 640212540c..08080658a2 100644 --- a/platform/features/conductor/test/ConductorServiceSpec.js +++ b/platform/features/conductor/test/ConductorServiceSpec.js @@ -21,9 +21,6 @@ *****************************************************************************/ /*global define,describe,it,expect,beforeEach,waitsFor,jasmine*/ -/** - * EventSpec. Created by vwoeltje on 11/6/14. Modified by shale on 06/23/2015. - */ define( ["../src/ConductorService"], function (ConductorService) { @@ -38,7 +35,10 @@ define( beforeEach(function () { mockNow = jasmine.createSpy('now'); mockNow.andReturn(TEST_NOW); - conductorService = new ConductorService(mockNow); + conductorService = new ConductorService(mockNow, [ + { key: "d1", name: "Domain #1" }, + { key: "d2", name: "Domain #2" } + ]); }); it("initializes a time conductor around the current time", function () { diff --git a/platform/features/conductor/test/ConductorTelemetryDecoratorSpec.js b/platform/features/conductor/test/ConductorTelemetryDecoratorSpec.js index 9a5efc2448..6e768419c1 100644 --- a/platform/features/conductor/test/ConductorTelemetryDecoratorSpec.js +++ b/platform/features/conductor/test/ConductorTelemetryDecoratorSpec.js @@ -23,8 +23,8 @@ define( - ["../src/ConductorTelemetryDecorator"], - function (ConductorTelemetryDecorator) { + ["../src/ConductorTelemetryDecorator", "./TestTimeConductor"], + function (ConductorTelemetryDecorator, TestTimeConductor) { "use strict"; describe("ConductorTelemetryDecorator", function () { @@ -54,10 +54,7 @@ define( 'conductorService', ['getConductor'] ); - mockConductor = jasmine.createSpyObj( - 'conductor', - [ 'queryStart', 'queryEnd', 'displayStart', 'displayEnd' ] - ); + mockConductor = new TestTimeConductor(); mockPromise = jasmine.createSpyObj( 'promise', ['then'] @@ -78,10 +75,9 @@ define( return j * j * j; }); - mockConductor.queryStart.andReturn(-12321); - mockConductor.queryEnd.andReturn(-12321); mockConductor.displayStart.andReturn(42); mockConductor.displayEnd.andReturn(1977); + mockConductor.domain.andReturn("testDomain"); decorator = new ConductorTelemetryDecorator( mockConductorService, @@ -89,24 +85,72 @@ define( ); }); - it("adds display start/end times to historical requests", function () { + + describe("decorates historical requests", function () { + var request; + + beforeEach(function () { + decorator.requestTelemetry([{ someKey: "some value" }]); + request = mockTelemetryService.requestTelemetry + .mostRecentCall.args[0][0]; + }); + + it("with start times", function () { + expect(request.start).toEqual(mockConductor.displayStart()); + }); + + it("with end times", function () { + expect(request.end).toEqual(mockConductor.displayEnd()); + }); + + it("with domain selection", function () { + expect(request.domain).toEqual(mockConductor.domain()); + }); + }); + + describe("decorates subscription requests", function () { + var request; + + beforeEach(function () { + var mockCallback = jasmine.createSpy('callback'); + decorator.subscribe(mockCallback, [{ someKey: "some value" }]); + request = mockTelemetryService.subscribe + .mostRecentCall.args[1][0]; + }); + + it("with start times", function () { + expect(request.start).toEqual(mockConductor.displayStart()); + }); + + it("with end times", function () { + expect(request.end).toEqual(mockConductor.displayEnd()); + }); + + it("with domain selection", function () { + expect(request.domain).toEqual(mockConductor.domain()); + }); + }); + + it("adds display start/end times & domain selection to historical requests", function () { decorator.requestTelemetry([{ someKey: "some value" }]); expect(mockTelemetryService.requestTelemetry) .toHaveBeenCalledWith([{ someKey: "some value", start: mockConductor.displayStart(), - end: mockConductor.displayEnd() + end: mockConductor.displayEnd(), + domain: jasmine.any(String) }]); }); - it("adds display start/end times to subscription requests", function () { + it("adds display start/end times & domain selection to subscription requests", function () { var mockCallback = jasmine.createSpy('callback'); decorator.subscribe(mockCallback, [{ someKey: "some value" }]); expect(mockTelemetryService.subscribe) .toHaveBeenCalledWith(jasmine.any(Function), [{ someKey: "some value", start: mockConductor.displayStart(), - end: mockConductor.displayEnd() + end: mockConductor.displayEnd(), + domain: jasmine.any(String) }]); }); diff --git a/platform/features/conductor/test/TestTimeConductor.js b/platform/features/conductor/test/TestTimeConductor.js new file mode 100644 index 0000000000..01fed0c8fd --- /dev/null +++ b/platform/features/conductor/test/TestTimeConductor.js @@ -0,0 +1,50 @@ +/***************************************************************************** + * 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. + *****************************************************************************/ +/*global define,describe,it,expect,beforeEach,waitsFor,jasmine,spyOn*/ + +define( + ["../src/TimeConductor"], + function (TimeConductor) { + 'use strict'; + + function TestTimeConductor() { + var self = this; + + TimeConductor.apply(this, [ + 402514200000, + 444546000000, + [ + { key: "domain0", name: "Domain #1" }, + { key: "domain1", name: "Domain #2" } + ] + ]); + + Object.keys(TimeConductor.prototype).forEach(function (method) { + spyOn(self, method).andCallThrough(); + }); + } + + TestTimeConductor.prototype = TimeConductor.prototype; + + return TestTimeConductor; + } +); diff --git a/platform/features/conductor/test/TimeConductorSpec.js b/platform/features/conductor/test/TimeConductorSpec.js index 1e3859bf60..c9336a93b0 100644 --- a/platform/features/conductor/test/TimeConductorSpec.js +++ b/platform/features/conductor/test/TimeConductorSpec.js @@ -21,9 +21,6 @@ *****************************************************************************/ /*global define,describe,it,expect,beforeEach,waitsFor,jasmine*/ -/** - * EventSpec. Created by vwoeltje on 11/6/14. Modified by shale on 06/23/2015. - */ define( ["../src/TimeConductor"], function (TimeConductor) { @@ -32,12 +29,17 @@ define( describe("TimeConductor", function () { var testStart, testEnd, + testDomains, conductor; beforeEach(function () { testStart = 42; testEnd = 12321; - conductor = new TimeConductor(testStart, testEnd); + testDomains = [ + { key: "d1", name: "Domain #1" }, + { key: "d2", name: "Domain #2" } + ]; + conductor = new TimeConductor(testStart, testEnd, testDomains); }); it("provides accessors for query/display start/end times", function () { @@ -52,6 +54,25 @@ define( expect(conductor.displayEnd()).toEqual(4); }); + it("exposes domain options", function () { + expect(conductor.domainOptions()).toEqual(testDomains); + }); + + it("exposes the current domain choice", function () { + expect(conductor.domain()).toEqual(testDomains[0].key); + }); + + it("allows the domain choice to be changed", function () { + conductor.domain(testDomains[1].key); + expect(conductor.domain()).toEqual(testDomains[1].key); + }); + + it("throws an error on attempts to set an invalid domain", function () { + expect(function () { + conductor.domain("invalid-domain"); + }).toThrow(); + }); + }); } ); diff --git a/platform/features/layout/src/FixedController.js b/platform/features/layout/src/FixedController.js index f608f490f8..77c655e2cb 100644 --- a/platform/features/layout/src/FixedController.js +++ b/platform/features/layout/src/FixedController.js @@ -105,11 +105,13 @@ define( index ); - setDisplayedValue( - telemetryObject, - telemetrySeries.getRangeValue(index), - limit && datum && limit.evaluate(datum) - ); + if (index >= 0) { + setDisplayedValue( + telemetryObject, + telemetrySeries.getRangeValue(index), + limit && datum && limit.evaluate(datum) + ); + } } // Update the displayed value for this object diff --git a/platform/features/plot/src/SubPlot.js b/platform/features/plot/src/SubPlot.js index 06b7f7bb0f..dfcaadf352 100644 --- a/platform/features/plot/src/SubPlot.js +++ b/platform/features/plot/src/SubPlot.js @@ -64,6 +64,16 @@ define( this.updateTicks(); } + /** + * Tests whether this subplot has domain data to show for the current pan/zoom level. Absence of domain data + * implies that there is no range data displayed either + * @returns {boolean} true if domain data exists for the current pan/zoom level + */ + SubPlot.prototype.hasDomainData = function() { + return this.panZoomStack + && this.panZoomStack.getDimensions()[0] > 0; + }; + // Utility function for filtering out empty strings. function isNonEmpty(v) { return typeof v === 'string' && v !== ""; @@ -253,7 +263,10 @@ define( this.hovering = true; this.subPlotBounds = $event.target.getBoundingClientRect(); this.mousePosition = this.toMousePosition($event); - this.updateHoverCoordinates(); + //If there is a domain to display, show hover coordinates, otherwise hover coordinates are meaningless + if (this.hasDomainData()) { + this.updateHoverCoordinates(); + } if (this.marqueeStart) { this.updateMarqueeBox(); } diff --git a/platform/features/plot/src/elements/PlotTickGenerator.js b/platform/features/plot/src/elements/PlotTickGenerator.js index af18050955..f759b6bcd6 100644 --- a/platform/features/plot/src/elements/PlotTickGenerator.js +++ b/platform/features/plot/src/elements/PlotTickGenerator.js @@ -53,7 +53,8 @@ define( for (i = 0; i < count; i += 1) { result.push({ - label: format(i * step + start) + //If data to show, display label for each tick line, otherwise show lines but suppress labels. + label: span > 0 ? format(i * step + start) : '' }); } diff --git a/platform/features/plot/test/SubPlotSpec.js b/platform/features/plot/test/SubPlotSpec.js index 58cd19faab..f7a7b667e9 100644 --- a/platform/features/plot/test/SubPlotSpec.js +++ b/platform/features/plot/test/SubPlotSpec.js @@ -157,6 +157,15 @@ define( ); }); + it ("indicates when there is domain data shown", function () { + expect(subplot.hasDomainData()).toEqual(true); + }); + + it ("indicates when there is no domain data shown", function () { + mockPanZoomStack.getDimensions.andReturn([0,0]); + expect(subplot.hasDomainData()).toEqual(false); + }); + it("disallows marquee zoom when start and end Marquee is at the same position", function () { expect(mockPanZoomStack.pushPanZoom).not.toHaveBeenCalled(); diff --git a/platform/telemetry/src/TelemetryHandle.js b/platform/telemetry/src/TelemetryHandle.js index ae25fd9bfa..ff77d7b9e0 100644 --- a/platform/telemetry/src/TelemetryHandle.js +++ b/platform/telemetry/src/TelemetryHandle.js @@ -110,20 +110,23 @@ define( * Get the latest telemetry datum for this domain object. This * will be from real-time telemetry, unless an index is specified, * in which case it will be pulled from the historical telemetry - * series at the specified index. + * series at the specified index. If there is no latest available + * datum, this will return undefined. * * @param {DomainObject} domainObject the object of interest * @param {number} [index] the index of the data of interest * @returns {TelemetryDatum} the most recent datum */ self.getDatum = function (telemetryObject, index) { + function makeNewDatum(series) { + return series ? + subscription.makeDatum(telemetryObject, series, index) : + undefined; + } + return typeof index !== 'number' ? subscription.getDatum(telemetryObject) : - subscription.makeDatum( - telemetryObject, - this.getSeries(telemetryObject), - index - ); + makeNewDatum(this.getSeries(telemetryObject)); }; return self;