diff --git a/README.md b/README.md
index c36cbea653..42cd060282 100644
--- a/README.md
+++ b/README.md
@@ -67,7 +67,7 @@ as described above.
An example of this is expressed in `platform/framework`, which follows
bundle conventions.
-### Regression Testing
+### Functional Testing
The tests described above are all at the unit-level; an additional
test suite using [Protractor](https://angular.github.io/protractor/)
@@ -76,9 +76,9 @@ us under development, in the `protractor` folder.
To run:
* Install protractor following the instructions above.
-* `webdriver-manager start`
-* `node app.js -p 1984 -x platform/persistence/elastic -i example/persistence
-* `protractor protractor/conf.js`
+* `cd protractor`
+* `npm install`
+* `npm run all`
## Build
diff --git a/bundles.json b/bundles.json
index 0b97f1abab..898ca3d738 100644
--- a/bundles.json
+++ b/bundles.json
@@ -21,6 +21,7 @@
"platform/persistence/queue",
"platform/policy",
"platform/entanglement",
+ "platform/search",
"example/imagery",
"example/persistence",
diff --git a/circle.yml b/circle.yml
index b8f367a604..2a79a5ed93 100644
--- a/circle.yml
+++ b/circle.yml
@@ -4,3 +4,7 @@ deployment:
commands:
- ./build-docs.sh
- git push git@heroku.com:openmctweb-demo.git $CIRCLE_SHA1:refs/heads/master
+ openmctweb-staging-un:
+ branch: search
+ heroku:
+ appname: openmctweb-staging-un
diff --git a/platform/commonUI/general/res/css/forms.css b/platform/commonUI/general/res/css/forms.css
index ec41844773..b7b08b89e8 100644
--- a/platform/commonUI/general/res/css/forms.css
+++ b/platform/commonUI/general/res/css/forms.css
@@ -69,6 +69,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
+/*********************************************** FORM ELEMENTS */
/*
@mixin invokeMenu($baseColor: $colorBodyFg) {
$c: $baseColor;
@@ -182,27 +183,21 @@
line-height: 14px;
margin-right: 5px; }
/* line 89, ../sass/forms/_elems.scss */
- .form .form-row .controls input[type="text"] {
- height: 22px;
- line-height: 22px;
- margin-top: -4px;
- vertical-align: baseline; }
- /* line 96, ../sass/forms/_elems.scss */
.form .form-row .controls .l-med input[type="text"] {
width: 200px; }
- /* line 100, ../sass/forms/_elems.scss */
+ /* line 93, ../sass/forms/_elems.scss */
.form .form-row .controls .l-small input[type="text"] {
width: 50px; }
- /* line 104, ../sass/forms/_elems.scss */
+ /* line 97, ../sass/forms/_elems.scss */
.form .form-row .controls .l-numeric input[type="text"] {
text-align: right; }
- /* line 108, ../sass/forms/_elems.scss */
+ /* line 101, ../sass/forms/_elems.scss */
.form .form-row .controls .select {
margin-right: 5px; }
- /* line 113, ../sass/forms/_elems.scss */
+ /* line 106, ../sass/forms/_elems.scss */
.form .form-row .field-hints {
color: #666666; }
- /* line 117, ../sass/forms/_elems.scss */
+ /* line 110, ../sass/forms/_elems.scss */
.form .form-row .selector-list {
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
@@ -215,7 +210,7 @@
position: relative;
height: 150px;
overflow: auto; }
- /* line 128, ../sass/forms/_elems.scss */
+ /* line 121, ../sass/forms/_elems.scss */
.form .form-row .selector-list .wrapper {
overflow-y: auto;
position: absolute;
@@ -224,24 +219,24 @@
bottom: 5px;
left: 5px; }
-/* line 142, ../sass/forms/_elems.scss */
+/* line 135, ../sass/forms/_elems.scss */
label.form-control.checkbox input {
margin-right: 5px;
vertical-align: top; }
-/* line 148, ../sass/forms/_elems.scss */
+/* line 141, ../sass/forms/_elems.scss */
.hint,
.s-hint {
font-size: 0.9em; }
-/* line 153, ../sass/forms/_elems.scss */
+/* line 146, ../sass/forms/_elems.scss */
.l-result {
display: inline-block;
min-width: 32px;
min-height: 32px;
position: relative;
vertical-align: top; }
- /* line 160, ../sass/forms/_elems.scss */
+ /* line 153, ../sass/forms/_elems.scss */
.l-result div.s-hint {
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
@@ -276,18 +271,17 @@ label.form-control.checkbox input {
.edit-main textarea {
-moz-appearance: none;
-webkit-appearance: none;
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
- -moz-box-shadow: inset rgba(0, 0, 0, 0.5) 0 1px 5px;
- -webkit-box-shadow: inset rgba(0, 0, 0, 0.5) 0 1px 5px;
- box-shadow: inset rgba(0, 0, 0, 0.5) 0 1px 5px;
+ -moz-box-shadow: inset rgba(0, 0, 0, 0.65) 0 1px 4px;
+ -webkit-box-shadow: inset rgba(0, 0, 0, 0.65) 0 1px 4px;
+ box-shadow: inset rgba(0, 0, 0, 0.65) 0 1px 4px;
background: rgba(255, 255, 255, 0.1);
border: none;
- border-bottom: 1px solid rgba(255, 255, 255, 0.1);
color: #cccccc;
outline: none;
padding: 5px;
@@ -323,18 +317,17 @@ label.form-control.checkbox input {
input[type="text"] {
-moz-appearance: none;
-webkit-appearance: none;
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
- -moz-box-shadow: inset rgba(0, 0, 0, 0.5) 0 1px 5px;
- -webkit-box-shadow: inset rgba(0, 0, 0, 0.5) 0 1px 5px;
- box-shadow: inset rgba(0, 0, 0, 0.5) 0 1px 5px;
+ -moz-box-shadow: inset rgba(0, 0, 0, 0.65) 0 1px 4px;
+ -webkit-box-shadow: inset rgba(0, 0, 0, 0.65) 0 1px 4px;
+ box-shadow: inset rgba(0, 0, 0, 0.65) 0 1px 4px;
background: rgba(255, 255, 255, 0.1);
border: none;
- border-bottom: 1px solid rgba(255, 255, 255, 0.1);
color: #cccccc;
outline: none;
padding: 0 3px; }
@@ -374,9 +367,9 @@ input[type="text"] {
background-image: -moz-linear-gradient(#525252, #454545);
background-image: -webkit-linear-gradient(#525252, #454545);
background-image: linear-gradient(#525252, #454545);
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
@@ -463,18 +456,17 @@ input[type="text"] {
.channel-selector .treeview {
-moz-appearance: none;
-webkit-appearance: none;
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
- -moz-box-shadow: inset rgba(0, 0, 0, 0.5) 0 1px 5px;
- -webkit-box-shadow: inset rgba(0, 0, 0, 0.5) 0 1px 5px;
- box-shadow: inset rgba(0, 0, 0, 0.5) 0 1px 5px;
+ -moz-box-shadow: inset rgba(0, 0, 0, 0.65) 0 1px 4px;
+ -webkit-box-shadow: inset rgba(0, 0, 0, 0.65) 0 1px 4px;
+ box-shadow: inset rgba(0, 0, 0, 0.65) 0 1px 4px;
background: rgba(255, 255, 255, 0.1);
border: none;
- border-bottom: 1px solid rgba(255, 255, 255, 0.1);
color: #cccccc;
outline: none;
padding: 0 3px;
diff --git a/platform/commonUI/general/res/css/items.css b/platform/commonUI/general/res/css/items.css
index c0ba5edecf..5caa262048 100644
--- a/platform/commonUI/general/res/css/items.css
+++ b/platform/commonUI/general/res/css/items.css
@@ -69,6 +69,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
+/*********************************************** FORM ELEMENTS */
/*
@mixin invokeMenu($baseColor: $colorBodyFg) {
$c: $baseColor;
@@ -115,9 +116,9 @@
background-image: -moz-linear-gradient(#5e5e5e, #525252);
background-image: -webkit-linear-gradient(#5e5e5e, #525252);
background-image: linear-gradient(#5e5e5e, #525252);
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
@@ -255,9 +256,9 @@
background-image: -moz-linear-gradient(#0ac2ff, #00b4f0);
background-image: -webkit-linear-gradient(#0ac2ff, #00b4f0);
background-image: linear-gradient(#0ac2ff, #00b4f0);
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
diff --git a/platform/commonUI/general/res/css/theme-espresso.css b/platform/commonUI/general/res/css/theme-espresso.css
index e4e1243d5a..b6c9a43edc 100644
--- a/platform/commonUI/general/res/css/theme-espresso.css
+++ b/platform/commonUI/general/res/css/theme-espresso.css
@@ -169,13 +169,14 @@ article, aside, details, figcaption, figure, footer, header, hgroup, main, menu,
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
+/*********************************************** FORM ELEMENTS */
/*
@mixin invokeMenu($baseColor: $colorBodyFg) {
- $c: $baseColor;
- color: $c;
- &:hover {
- color: lighten($c, $ltGamma);
- }
+ $c: $baseColor;
+ color: $c;
+ &:hover {
+ color: lighten($c, $ltGamma);
+ }
}
*/
/*****************************************************************************
@@ -316,10 +317,15 @@ input, textarea {
font-family: Helvetica, Arial, sans-serif; }
/* line 53, ../sass/_global.scss */
+input[type="text"] {
+ vertical-align: baseline;
+ padding: 3px 5px !important; }
+
+/* line 58, ../sass/_global.scss */
h1, h2, h3 {
margin: 0; }
-/* line 57, ../sass/_global.scss */
+/* line 62, ../sass/_global.scss */
h1 {
font-size: 1.7em;
font-weight: normal !important;
@@ -327,21 +333,21 @@ h1 {
margin-bottom: 20px;
margin-top: 0; }
-/* line 65, ../sass/_global.scss */
+/* line 70, ../sass/_global.scss */
p {
margin-bottom: 10px; }
-/* line 69, ../sass/_global.scss */
+/* line 74, ../sass/_global.scss */
span {
/* 618 DEBUG
box-sizing: border-box;
*/ }
-/* line 75, ../sass/_global.scss */
+/* line 80, ../sass/_global.scss */
mct-container {
display: block; }
-/* line 79, ../sass/_global.scss */
+/* line 84, ../sass/_global.scss */
.abs, .btn-menu span.l-click-area {
position: absolute;
top: 0;
@@ -351,51 +357,51 @@ mct-container {
height: auto;
width: auto; }
-/* line 89, ../sass/_global.scss */
+/* line 94, ../sass/_global.scss */
.code, .codehilite {
font-family: "Lucida Console", monospace;
font-size: 0.7em;
line-height: 150%;
white-space: pre; }
-/* line 96, ../sass/_global.scss */
+/* line 101, ../sass/_global.scss */
.codehilite {
background-color: rgba(255, 255, 255, 0.1);
padding: 1em; }
-/* line 102, ../sass/_global.scss */
+/* line 107, ../sass/_global.scss */
.align-right {
text-align: right; }
-/* line 106, ../sass/_global.scss */
+/* line 111, ../sass/_global.scss */
.centered {
text-align: center; }
-/* line 110, ../sass/_global.scss */
+/* line 115, ../sass/_global.scss */
.no-margin {
margin: 0; }
-/* line 114, ../sass/_global.scss */
+/* line 119, ../sass/_global.scss */
.colorKey {
color: #0099cc; }
-/* line 118, ../sass/_global.scss */
+/* line 123, ../sass/_global.scss */
.ds {
-moz-box-shadow: rgba(0, 0, 0, 0.7) 0 4px 10px 2px;
-webkit-box-shadow: rgba(0, 0, 0, 0.7) 0 4px 10px 2px;
box-shadow: rgba(0, 0, 0, 0.7) 0 4px 10px 2px; }
-/* line 122, ../sass/_global.scss */
+/* line 127, ../sass/_global.scss */
.hide,
.hidden {
display: none !important; }
-/* line 128, ../sass/_global.scss */
+/* line 133, ../sass/_global.scss */
.paused:not(.s-btn):not(.icon-btn) {
border-color: #c56f01 !important;
color: #c56f01 !important; }
-/* line 134, ../sass/_global.scss */
+/* line 139, ../sass/_global.scss */
.sep {
color: rgba(255, 255, 255, 0.2); }
@@ -955,67 +961,6 @@ mct-container {
.s-text h3 {
margin-top: 2em; }
-/*****************************************************************************
- * 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.
- *****************************************************************************/
-/* line 22, ../sass/_badges.scss */
-.badge {
- background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZDIzMyIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmYzcwMCIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');
- background-size: 100%;
- background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffd233), color-stop(100%, #ffc700));
- background-image: -moz-linear-gradient(#ffd233, #ffc700);
- background-image: -webkit-linear-gradient(#ffd233, #ffc700);
- background-image: linear-gradient(#ffd233, #ffc700);
- color: #333;
- display: inline-block;
- text-align: center; }
-
-/* line 29, ../sass/_badges.scss */
-.top-bar .badge {
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
- border-radius: 3px;
- font-size: 1.4em;
- height: 25px;
- line-height: 25px;
- margin-right: 5px;
- width: 35px;
- vertical-align: middle; }
-
-/* line 54, ../sass/_badges.scss */
-.super-menu .badge {
- background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwYmZmZiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzAwOTljYyIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');
- background-size: 100%;
- background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #00bfff), color-stop(100%, #0099cc));
- background-image: -moz-linear-gradient(#00bfff, #0099cc);
- background-image: -webkit-linear-gradient(#00bfff, #0099cc);
- background-image: linear-gradient(#00bfff, #0099cc);
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
- -moz-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px;
- -webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px;
- box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px;
- padding: 2px 7px; }
-
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
@@ -1104,27 +1049,27 @@ mct-container {
/*.s-limit-upr,
.s-limit-lwr {
- $a: 0.5;
- $l: 30%;
- white-space: nowrap;
- &:before {
- display: inline-block;
- font-family: symbolsfont;
- font-size: 0.85em;
- font-style: normal !important;
- margin-right: $interiorMarginSm;
- vertical-align: middle;
- }
+ $a: 0.5;
+ $l: 30%;
+ white-space: nowrap;
+ &:before {
+ display: inline-block;
+ font-family: symbolsfont;
+ font-size: 0.85em;
+ font-style: normal !important;
+ margin-right: $interiorMarginSm;
+ vertical-align: middle;
+ }
}
.s-limit-upr {
- &.s-limit-yellow { @include limit($colorLimitYellow, "\0000ed"); }
- &.s-limit-red { @include limit($colorLimitRed, "\0000eb"); }
+ &.s-limit-yellow { @include limit($colorLimitYellow, "\0000ed"); }
+ &.s-limit-red { @include limit($colorLimitRed, "\0000eb"); }
}
.s-limit-lwr {
- &.s-limit-yellow { @include limit($colorLimitYellow, "\0000ec"); }
- &.s-limit-red { @include limit($colorLimitRed, "\0000ee"); }
+ &.s-limit-yellow { @include limit($colorLimitYellow, "\0000ec"); }
+ &.s-limit-red { @include limit($colorLimitRed, "\0000ee"); }
}*/
/* line 35, ../sass/_limits.scss */
[class*="s-limit"] {
@@ -1206,7 +1151,8 @@ mct-container {
height: 100%; }
/* line 27, ../sass/lists/_tabular.scss */
-.tabular {
+.tabular,
+table {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
@@ -1214,98 +1160,187 @@ mct-container {
border-collapse: collapse;
color: #fff;
display: table;
- font-size: 0.75em;
+ font-size: 0.75rem;
position: relative;
width: 100%; }
- /* line 37, ../sass/lists/_tabular.scss */
+ /* line 38, ../sass/lists/_tabular.scss */
.tabular thead, .tabular .thead,
- .tabular tbody tr, .tabular .tbody .tr {
+ .tabular tbody tr, .tabular .tbody .tr,
+ table thead,
+ table .thead,
+ table tbody tr,
+ table .tbody .tr {
width: 100%; }
- /* line 45, ../sass/lists/_tabular.scss */
- .tabular thead tr, .tabular thead .tr, .tabular .thead tr, .tabular .thead .tr {
- height: 18px; }
- /* line 48, ../sass/lists/_tabular.scss */
- .tabular thead:before, .tabular .thead:before {
- content: "";
- display: block;
- z-index: 0;
- position: absolute;
- width: 100%;
- height: 18px;
- background: rgba(255, 255, 255, 0.15); }
- /* line 58, ../sass/lists/_tabular.scss */
- .tabular tbody, .tabular .tbody {
+ /* line 44, ../sass/lists/_tabular.scss */
+ .tabular thead, .tabular .thead,
+ table thead,
+ table .thead {
+ border-bottom: 1px solid #333; }
+ /* line 47, ../sass/lists/_tabular.scss */
+ .tabular tbody, .tabular .tbody,
+ table tbody,
+ table .tbody {
display: table-row-group; }
- /* line 65, ../sass/lists/_tabular.scss */
- .tabular tbody tr:hover, .tabular tbody .tr:hover, .tabular .tbody tr:hover, .tabular .tbody .tr:hover {
+ /* line 54, ../sass/lists/_tabular.scss */
+ .tabular tbody tr:hover, .tabular tbody .tr:hover, .tabular .tbody tr:hover, .tabular .tbody .tr:hover,
+ table tbody tr:hover,
+ table tbody .tr:hover,
+ table .tbody tr:hover,
+ table .tbody .tr:hover {
background: rgba(255, 255, 255, 0.1); }
- /* line 70, ../sass/lists/_tabular.scss */
- .tabular tr, .tabular .tr {
+ /* line 59, ../sass/lists/_tabular.scss */
+ .tabular tr, .tabular .tr,
+ table tr,
+ table .tr {
display: table-row; }
- /* line 72, ../sass/lists/_tabular.scss */
- .tabular tr:first-child .td, .tabular .tr:first-child .td {
+ /* line 61, ../sass/lists/_tabular.scss */
+ .tabular tr:first-child .td, .tabular .tr:first-child .td,
+ table tr:first-child .td,
+ table .tr:first-child .td {
border-top: none; }
- /* line 75, ../sass/lists/_tabular.scss */
- .tabular tr th, .tabular tr .th, .tabular tr td, .tabular tr .td, .tabular .tr th, .tabular .tr .th, .tabular .tr td, .tabular .tr .td {
+ /* line 65, ../sass/lists/_tabular.scss */
+ .tabular tr.group-header td, .tabular tr.group-header .td, .tabular .tr.group-header td, .tabular .tr.group-header .td,
+ table tr.group-header td,
+ table tr.group-header .td,
+ table .tr.group-header td,
+ table .tr.group-header .td {
+ background-color: #404040;
+ color: #a6a6a6; }
+ /* line 71, ../sass/lists/_tabular.scss */
+ .tabular tr th, .tabular tr .th, .tabular tr td, .tabular tr .td, .tabular .tr th, .tabular .tr .th, .tabular .tr td, .tabular .tr .td,
+ table tr th,
+ table tr .th,
+ table tr td,
+ table tr .td,
+ table .tr th,
+ table .tr .th,
+ table .tr td,
+ table .tr .td {
display: table-cell; }
- /* line 78, ../sass/lists/_tabular.scss */
- .tabular tr th, .tabular tr .th, .tabular .tr th, .tabular .tr .th {
- border: none;
- border-left: 1px solid rgba(255, 255, 255, 0.1);
+ /* line 74, ../sass/lists/_tabular.scss */
+ .tabular tr th, .tabular tr .th, .tabular .tr th, .tabular .tr .th,
+ table tr th,
+ table tr .th,
+ table .tr th,
+ table .tr .th {
+ background-color: #4d4d4d;
+ border-left: 1px solid #333;
color: #b3b3b3;
- padding: 0 5px;
+ padding: 5px 5px;
white-space: nowrap;
vertical-align: middle; }
- /* line 85, ../sass/lists/_tabular.scss */
- .tabular tr th:first-child, .tabular tr .th:first-child, .tabular .tr th:first-child, .tabular .tr .th:first-child {
+ /* line 81, ../sass/lists/_tabular.scss */
+ .tabular tr th:first-child, .tabular tr .th:first-child, .tabular .tr th:first-child, .tabular .tr .th:first-child,
+ table tr th:first-child,
+ table tr .th:first-child,
+ table .tr th:first-child,
+ table .tr .th:first-child {
border-left: none; }
- /* line 89, ../sass/lists/_tabular.scss */
- .tabular tr th.sort .icon-sorting:before, .tabular tr .th.sort .icon-sorting:before, .tabular .tr th.sort .icon-sorting:before, .tabular .tr .th.sort .icon-sorting:before {
+ /* line 85, ../sass/lists/_tabular.scss */
+ .tabular tr th.sort .icon-sorting:before, .tabular tr .th.sort .icon-sorting:before, .tabular .tr th.sort .icon-sorting:before, .tabular .tr .th.sort .icon-sorting:before,
+ table tr th.sort .icon-sorting:before,
+ table tr .th.sort .icon-sorting:before,
+ table .tr th.sort .icon-sorting:before,
+ table .tr .th.sort .icon-sorting:before {
display: inline-block;
font-family: symbolsfont;
margin-left: 5px; }
- /* line 94, ../sass/lists/_tabular.scss */
- .tabular tr th.sort.asc .icon-sorting:before, .tabular tr .th.sort.asc .icon-sorting:before, .tabular .tr th.sort.asc .icon-sorting:before, .tabular .tr .th.sort.asc .icon-sorting:before {
+ /* line 90, ../sass/lists/_tabular.scss */
+ .tabular tr th.sort.asc .icon-sorting:before, .tabular tr .th.sort.asc .icon-sorting:before, .tabular .tr th.sort.asc .icon-sorting:before, .tabular .tr .th.sort.asc .icon-sorting:before,
+ table tr th.sort.asc .icon-sorting:before,
+ table tr .th.sort.asc .icon-sorting:before,
+ table .tr th.sort.asc .icon-sorting:before,
+ table .tr .th.sort.asc .icon-sorting:before {
content: '0'; }
- /* line 97, ../sass/lists/_tabular.scss */
- .tabular tr th.sort.desc .icon-sorting:before, .tabular tr .th.sort.desc .icon-sorting:before, .tabular .tr th.sort.desc .icon-sorting:before, .tabular .tr .th.sort.desc .icon-sorting:before {
+ /* line 93, ../sass/lists/_tabular.scss */
+ .tabular tr th.sort.desc .icon-sorting:before, .tabular tr .th.sort.desc .icon-sorting:before, .tabular .tr th.sort.desc .icon-sorting:before, .tabular .tr .th.sort.desc .icon-sorting:before,
+ table tr th.sort.desc .icon-sorting:before,
+ table tr .th.sort.desc .icon-sorting:before,
+ table .tr th.sort.desc .icon-sorting:before,
+ table .tr .th.sort.desc .icon-sorting:before {
content: '1'; }
- /* line 102, ../sass/lists/_tabular.scss */
- .tabular tr td, .tabular tr .td, .tabular .tr td, .tabular .tr .td {
- border-top: 1px solid rgba(255, 255, 255, 0.1);
- min-width: 110px;
+ /* line 98, ../sass/lists/_tabular.scss */
+ .tabular tr td, .tabular tr .td, .tabular .tr td, .tabular .tr .td,
+ table tr td,
+ table tr .td,
+ table .tr td,
+ table .tr .td {
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+ min-width: 20px;
color: #fff;
- padding: 2px 5px;
+ padding: 3px 5px;
+ word-wrap: break-word;
vertical-align: top; }
+ /* line 105, ../sass/lists/_tabular.scss */
+ .tabular tr td.numeric, .tabular tr .td.numeric, .tabular .tr td.numeric, .tabular .tr .td.numeric,
+ table tr td.numeric,
+ table tr .td.numeric,
+ table .tr td.numeric,
+ table .tr .td.numeric {
+ text-align: right; }
/* line 108, ../sass/lists/_tabular.scss */
- .tabular tr td.numeric, .tabular tr .td.numeric, .tabular .tr td.numeric, .tabular .tr .td.numeric {
+ .tabular tr td.s-cell-type-value, .tabular tr .td.s-cell-type-value, .tabular .tr td.s-cell-type-value, .tabular .tr .td.s-cell-type-value,
+ table tr td.s-cell-type-value,
+ table tr .td.s-cell-type-value,
+ table .tr td.s-cell-type-value,
+ table .tr .td.s-cell-type-value {
text-align: right; }
- /* line 111, ../sass/lists/_tabular.scss */
- .tabular tr td.s-cell-type-value, .tabular tr .td.s-cell-type-value, .tabular .tr td.s-cell-type-value, .tabular .tr .td.s-cell-type-value {
- text-align: right; }
- /* line 113, ../sass/lists/_tabular.scss */
- .tabular tr td.s-cell-type-value .l-cell-contents, .tabular tr .td.s-cell-type-value .l-cell-contents, .tabular .tr td.s-cell-type-value .l-cell-contents, .tabular .tr .td.s-cell-type-value .l-cell-contents {
+ /* line 110, ../sass/lists/_tabular.scss */
+ .tabular tr td.s-cell-type-value .l-cell-contents, .tabular tr .td.s-cell-type-value .l-cell-contents, .tabular .tr td.s-cell-type-value .l-cell-contents, .tabular .tr .td.s-cell-type-value .l-cell-contents,
+ table tr td.s-cell-type-value .l-cell-contents,
+ table tr .td.s-cell-type-value .l-cell-contents,
+ table .tr td.s-cell-type-value .l-cell-contents,
+ table .tr .td.s-cell-type-value .l-cell-contents {
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
border-radius: 2px;
padding-left: 5px;
padding-right: 5px; }
- /* line 122, ../sass/lists/_tabular.scss */
- .tabular.filterable tbody, .tabular.filterable .tbody {
- top: 36px; }
- /* line 127, ../sass/lists/_tabular.scss */
- .tabular.fixed-header {
+ /* line 126, ../sass/lists/_tabular.scss */
+ .tabular.filterable tbody, .tabular.filterable .tbody,
+ table.filterable tbody,
+ table.filterable .tbody {
+ top: 44px; }
+ /* line 129, ../sass/lists/_tabular.scss */
+ .tabular.filterable input[type="text"],
+ table.filterable input[type="text"] {
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ width: 100%; }
+ /* line 135, ../sass/lists/_tabular.scss */
+ .tabular.fixed-header,
+ table.fixed-header {
height: 100%; }
- /* line 129, ../sass/lists/_tabular.scss */
+ /* line 137, ../sass/lists/_tabular.scss */
.tabular.fixed-header thead, .tabular.fixed-header .thead,
- .tabular.fixed-header tbody tr, .tabular.fixed-header .tbody .tr {
+ .tabular.fixed-header tbody tr, .tabular.fixed-header .tbody .tr,
+ table.fixed-header thead,
+ table.fixed-header .thead,
+ table.fixed-header tbody tr,
+ table.fixed-header .tbody .tr {
display: table;
table-layout: fixed; }
- /* line 134, ../sass/lists/_tabular.scss */
- .tabular.fixed-header thead, .tabular.fixed-header .thead {
+ /* line 142, ../sass/lists/_tabular.scss */
+ .tabular.fixed-header thead, .tabular.fixed-header .thead,
+ table.fixed-header thead,
+ table.fixed-header .thead {
width: calc(100% - 10px); }
- /* line 137, ../sass/lists/_tabular.scss */
- .tabular.fixed-header tbody, .tabular.fixed-header .tbody {
+ /* line 144, ../sass/lists/_tabular.scss */
+ .tabular.fixed-header thead:before, .tabular.fixed-header .thead:before,
+ table.fixed-header thead:before,
+ table.fixed-header .thead:before {
+ content: "";
+ display: block;
+ z-index: 0;
+ position: absolute;
+ width: 100%;
+ height: 22px;
+ background: rgba(255, 255, 255, 0.15); }
+ /* line 154, ../sass/lists/_tabular.scss */
+ .tabular.fixed-header tbody, .tabular.fixed-header .tbody,
+ table.fixed-header tbody,
+ table.fixed-header .tbody {
overflow: hidden;
position: absolute;
top: 0;
@@ -1314,11 +1349,13 @@ mct-container {
left: 0;
width: auto;
height: auto;
- top: 18px;
+ top: 22px;
display: block;
overflow-y: scroll; }
- /* line 145, ../sass/lists/_tabular.scss */
- .tabular.t-event-messages td, .tabular.t-event-messages .td {
+ /* line 162, ../sass/lists/_tabular.scss */
+ .tabular.t-event-messages td, .tabular.t-event-messages .td,
+ table.t-event-messages td,
+ table.t-event-messages .td {
min-width: 150px; }
/* line 1, ../sass/controls/_breadcrumb.scss */
@@ -1418,9 +1455,9 @@ mct-container {
.s-btn,
.icon-btn,
.s-icon-btn {
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
@@ -1438,9 +1475,9 @@ mct-container {
background-image: -moz-linear-gradient(#0ac2ff, #00b4f0);
background-image: -webkit-linear-gradient(#0ac2ff, #00b4f0);
background-image: linear-gradient(#0ac2ff, #00b4f0);
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
@@ -1487,9 +1524,9 @@ mct-container {
background-image: -moz-linear-gradient(#24c8ff, #0ac2ff);
background-image: -webkit-linear-gradient(#24c8ff, #0ac2ff);
background-image: linear-gradient(#24c8ff, #0ac2ff);
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
@@ -1541,9 +1578,9 @@ mct-container {
background-image: -moz-linear-gradient(#858585, #787878);
background-image: -webkit-linear-gradient(#858585, #787878);
background-image: linear-gradient(#858585, #787878);
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
@@ -1592,9 +1629,9 @@ mct-container {
background-image: -moz-linear-gradient(#525252, #454545);
background-image: -webkit-linear-gradient(#525252, #454545);
background-image: linear-gradient(#525252, #454545);
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
@@ -1652,9 +1689,9 @@ mct-container {
background-image: -moz-linear-gradient(#fe9105, #e98301);
background-image: -webkit-linear-gradient(#fe9105, #e98301);
background-image: linear-gradient(#fe9105, #e98301);
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
@@ -1735,11 +1772,11 @@ mct-container {
/* line 132, ../sass/controls/_buttons.scss */
.icon-btn.pause-play,
.s-icon-btn.pause-play {
- /* &.paused {
- .icon {
- @include pulse(500ms);
- }
- }*/ }
+ /* &.paused {
+ .icon {
+ @include pulse(500ms);
+ }
+ }*/ }
/* line 138, ../sass/controls/_buttons.scss */
.icon-btn.pause-play .icon:before,
.s-icon-btn.pause-play .icon:before {
@@ -1862,32 +1899,32 @@ a.l-btn span {
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*.control {
- // UNUSED?
- &.view-control {
- .icon {
- display: inline-block;
- margin: -1px 5px 1px 2px;
- vertical-align: middle;
- &.triangle-down {
- margin: 2px 2px -2px 0px;
- }
- }
+ // UNUSED?
+ &.view-control {
+ .icon {
+ display: inline-block;
+ margin: -1px 5px 1px 2px;
+ vertical-align: middle;
+ &.triangle-down {
+ margin: 2px 2px -2px 0px;
+ }
+ }
- .label {
- display: inline-block;
- font-size: 11px;
- vertical-align: middle;
- }
+ .label {
+ display: inline-block;
+ font-size: 11px;
+ vertical-align: middle;
+ }
- .toggle {
- @include border-radius(3px);
- display: inline-block;
- padding: 1px 6px 4px 4px;
- &:hover {
- background: rgba(white, 0.1);
- }
- }
- }
+ .toggle {
+ @include border-radius(3px);
+ display: inline-block;
+ padding: 1px 6px 4px 4px;
+ &:hover {
+ background: rgba(white, 0.1);
+ }
+ }
+ }
}*/
/* line 51, ../sass/controls/_controls.scss */
.accordion {
@@ -1997,21 +2034,21 @@ a.l-btn span {
.btn-set .btn:first-child,
.btn-set .t-btn:first-child {
border-left: none;
- -moz-border-radius-topleft: 2px;
- -webkit-border-top-left-radius: 2px;
- border-top-left-radius: 2px;
- -moz-border-radius-bottomleft: 2px;
- -webkit-border-bottom-left-radius: 2px;
- border-bottom-left-radius: 2px; }
+ -moz-border-radius-topleft: 3px;
+ -webkit-border-top-left-radius: 3px;
+ border-top-left-radius: 3px;
+ -moz-border-radius-bottomleft: 3px;
+ -webkit-border-bottom-left-radius: 3px;
+ border-bottom-left-radius: 3px; }
/* line 169, ../sass/controls/_controls.scss */
.btn-set .btn:last-child,
.btn-set .t-btn:last-child {
- -moz-border-radius-topright: 2px;
- -webkit-border-top-right-radius: 2px;
- border-top-right-radius: 2px;
- -moz-border-radius-bottomright: 2px;
- -webkit-border-bottom-right-radius: 2px;
- border-bottom-right-radius: 2px; }
+ -moz-border-radius-topright: 3px;
+ -webkit-border-top-right-radius: 3px;
+ border-top-right-radius: 3px;
+ -moz-border-radius-bottomright: 3px;
+ -webkit-border-bottom-right-radius: 3px;
+ border-bottom-right-radius: 3px; }
/* line 175, ../sass/controls/_controls.scss */
.object-browse-bar .btn,
@@ -2111,9 +2148,9 @@ label.checkbox.custom {
background-image: -moz-linear-gradient(#525252, #454545);
background-image: -webkit-linear-gradient(#525252, #454545);
background-image: linear-gradient(#525252, #454545);
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
@@ -2124,23 +2161,23 @@ label.checkbox.custom {
border-top: 1px solid #575757;
color: #999;
display: inline-block;
- /* height: $h;
- line-height: $h;
- &.dropdown {
- padding-left: $p;
- padding-right: $p;
- }*/
- /* &.context-available {
- // An element like the invoke-menu triangle;
- // Indicates that this element has a dropdown menu available;
- // Currently unused
- $c: $colorKey;
- color: $c;
- padding: 0 5px;
- &:hover {
- color: lighten($c, 10%);
- }
- }*/ }
+ /* height: $h;
+ line-height: $h;
+ &.dropdown {
+ padding-left: $p;
+ padding-right: $p;
+ }*/
+ /* &.context-available {
+ // An element like the invoke-menu triangle;
+ // Indicates that this element has a dropdown menu available;
+ // Currently unused
+ $c: $colorKey;
+ color: $c;
+ padding: 0 5px;
+ &:hover {
+ color: lighten($c, 10%);
+ }
+ }*/ }
/* line 162, ../sass/_mixins.scss */
.btn-menu:not(.disabled):hover {
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzYzNjM2MyIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzU3NTc1NyIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');
@@ -2182,9 +2219,9 @@ label.checkbox.custom {
padding-left: 25px; }
/* line 335, ../sass/controls/_controls.scss */
.top-bar .btn-menu.browse-btn .badge {
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
- border-radius: 3px;
+ -moz-border-radius: 4.5px;
+ -webkit-border-radius: 4.5px;
+ border-radius: 4.5px;
display: block;
font-size: 1em;
line-height: 15px;
@@ -2278,9 +2315,9 @@ label.checkbox.custom {
background-image: -moz-linear-gradient(#525252, #454545);
background-image: -webkit-linear-gradient(#525252, #454545);
background-image: linear-gradient(#525252, #454545);
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
@@ -2492,9 +2529,9 @@ label.checkbox.custom {
background-image: -moz-linear-gradient(#5e5e5e, #525252);
background-image: -webkit-linear-gradient(#5e5e5e, #525252);
background-image: linear-gradient(#5e5e5e, #525252);
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
@@ -2517,7 +2554,7 @@ label.checkbox.custom {
.menu-element .menu ul {
margin: 0;
padding: 0; }
- /* line 276, ../sass/_mixins.scss */
+ /* line 308, ../sass/_mixins.scss */
.menu-element .menu ul li {
list-style-type: none;
margin: 0;
@@ -2555,9 +2592,9 @@ label.checkbox.custom {
background-image: -moz-linear-gradient(#8c8c8c, #808080);
background-image: -webkit-linear-gradient(#8c8c8c, #808080);
background-image: linear-gradient(#8c8c8c, #808080);
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
@@ -2623,9 +2660,9 @@ label.checkbox.custom {
overflow-y: auto; }
/* line 119, ../sass/controls/_menus.scss */
.menu-element .super-menu .pane.left ul li {
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
padding-left: 30px;
border-top: none; }
/* line 126, ../sass/controls/_menus.scss */
@@ -3116,27 +3153,6 @@ label.checkbox.custom {
font-size: 0.65em;
vertical-align: top; }
-/*****************************************************************************
- * 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.
- *****************************************************************************/
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
@@ -3220,27 +3236,21 @@ label.checkbox.custom {
line-height: 14px;
margin-right: 5px; }
/* line 89, ../sass/forms/_elems.scss */
- .form .form-row .controls input[type="text"] {
- height: 22px;
- line-height: 22px;
- margin-top: -4px;
- vertical-align: baseline; }
- /* line 96, ../sass/forms/_elems.scss */
.form .form-row .controls .l-med input[type="text"] {
width: 200px; }
- /* line 100, ../sass/forms/_elems.scss */
+ /* line 93, ../sass/forms/_elems.scss */
.form .form-row .controls .l-small input[type="text"] {
width: 50px; }
- /* line 104, ../sass/forms/_elems.scss */
+ /* line 97, ../sass/forms/_elems.scss */
.form .form-row .controls .l-numeric input[type="text"] {
text-align: right; }
- /* line 108, ../sass/forms/_elems.scss */
+ /* line 101, ../sass/forms/_elems.scss */
.form .form-row .controls .select {
margin-right: 5px; }
- /* line 113, ../sass/forms/_elems.scss */
+ /* line 106, ../sass/forms/_elems.scss */
.form .form-row .field-hints {
color: #666666; }
- /* line 117, ../sass/forms/_elems.scss */
+ /* line 110, ../sass/forms/_elems.scss */
.form .form-row .selector-list {
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
@@ -3253,7 +3263,7 @@ label.checkbox.custom {
position: relative;
height: 150px;
overflow: auto; }
- /* line 128, ../sass/forms/_elems.scss */
+ /* line 121, ../sass/forms/_elems.scss */
.form .form-row .selector-list .wrapper {
overflow-y: auto;
position: absolute;
@@ -3262,24 +3272,24 @@ label.checkbox.custom {
bottom: 5px;
left: 5px; }
-/* line 142, ../sass/forms/_elems.scss */
+/* line 135, ../sass/forms/_elems.scss */
label.form-control.checkbox input {
margin-right: 5px;
vertical-align: top; }
-/* line 148, ../sass/forms/_elems.scss */
+/* line 141, ../sass/forms/_elems.scss */
.hint,
.s-hint {
font-size: 0.9em; }
-/* line 153, ../sass/forms/_elems.scss */
+/* line 146, ../sass/forms/_elems.scss */
.l-result {
display: inline-block;
min-width: 32px;
min-height: 32px;
position: relative;
vertical-align: top; }
- /* line 160, ../sass/forms/_elems.scss */
+ /* line 153, ../sass/forms/_elems.scss */
.l-result div.s-hint {
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
@@ -3373,22 +3383,21 @@ span.req {
input[type="text"] {
-moz-appearance: none;
-webkit-appearance: none;
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
- -moz-box-shadow: inset rgba(0, 0, 0, 0.5) 0 1px 5px;
- -webkit-box-shadow: inset rgba(0, 0, 0, 0.5) 0 1px 5px;
- box-shadow: inset rgba(0, 0, 0, 0.5) 0 1px 5px;
+ -moz-box-shadow: inset rgba(0, 0, 0, 0.65) 0 1px 4px;
+ -webkit-box-shadow: inset rgba(0, 0, 0, 0.65) 0 1px 4px;
+ box-shadow: inset rgba(0, 0, 0, 0.65) 0 1px 4px;
background: rgba(255, 255, 255, 0.1);
border: none;
- border-bottom: 1px solid rgba(255, 255, 255, 0.1);
color: #cccccc;
outline: none;
padding: 0 3px; }
- /* line 33, ../sass/forms/_mixins.scss */
+ /* line 274, ../sass/_mixins.scss */
input[type="text"].error {
background: rgba(255, 0, 0, 0.5); }
/* line 29, ../sass/forms/_text-input.scss */
@@ -3424,9 +3433,9 @@ input[type="text"] {
background-image: -moz-linear-gradient(#525252, #454545);
background-image: -webkit-linear-gradient(#525252, #454545);
background-image: linear-gradient(#525252, #454545);
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
@@ -3513,18 +3522,17 @@ input[type="text"] {
.channel-selector .treeview {
-moz-appearance: none;
-webkit-appearance: none;
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
- -moz-box-shadow: inset rgba(0, 0, 0, 0.5) 0 1px 5px;
- -webkit-box-shadow: inset rgba(0, 0, 0, 0.5) 0 1px 5px;
- box-shadow: inset rgba(0, 0, 0, 0.5) 0 1px 5px;
+ -moz-box-shadow: inset rgba(0, 0, 0, 0.65) 0 1px 4px;
+ -webkit-box-shadow: inset rgba(0, 0, 0, 0.65) 0 1px 4px;
+ box-shadow: inset rgba(0, 0, 0, 0.65) 0 1px 4px;
background: rgba(255, 255, 255, 0.1);
border: none;
- border-bottom: 1px solid rgba(255, 255, 255, 0.1);
color: #cccccc;
outline: none;
padding: 0 3px;
@@ -3534,7 +3542,7 @@ input[type="text"] {
max-height: 400px;
overflow: auto;
padding: 5px; }
- /* line 33, ../sass/forms/_mixins.scss */
+ /* line 274, ../sass/_mixins.scss */
.channel-selector .treeview.error {
background: rgba(255, 0, 0, 0.5); }
/* line 36, ../sass/forms/_channel-selector.scss */
@@ -3618,24 +3626,23 @@ input[type="text"] {
.t-filter input.t-filter-input {
-moz-appearance: none;
-webkit-appearance: none;
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
- -moz-box-shadow: inset rgba(0, 0, 0, 0.5) 0 1px 5px;
- -webkit-box-shadow: inset rgba(0, 0, 0, 0.5) 0 1px 5px;
- box-shadow: inset rgba(0, 0, 0, 0.5) 0 1px 5px;
+ -moz-box-shadow: inset rgba(0, 0, 0, 0.65) 0 1px 4px;
+ -webkit-box-shadow: inset rgba(0, 0, 0, 0.65) 0 1px 4px;
+ box-shadow: inset rgba(0, 0, 0, 0.65) 0 1px 4px;
background: rgba(255, 255, 255, 0.1);
border: none;
- border-bottom: 1px solid rgba(255, 255, 255, 0.1);
color: #cccccc;
outline: none;
padding: 0 3px;
background: #3b3b3b;
border-bottom: 1px solid #4d4d4d; }
- /* line 33, ../sass/forms/_mixins.scss */
+ /* line 274, ../sass/_mixins.scss */
.filter input.filter.error,
.filter input.t-filter-input.error,
.t-filter input.filter.error,
@@ -3653,9 +3660,9 @@ input[type="text"] {
/* line 42, ../sass/forms/_filter.scss */
.filter .icon.ui-symbol,
.t-filter .icon.ui-symbol {
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
display: inline-block;
font-size: 1.3em;
height: 22px;
@@ -3669,9 +3676,9 @@ input[type="text"] {
/* line 54, ../sass/forms/_filter.scss */
.filter .s-a-clear.ui-symbol,
.t-filter .s-a-clear.ui-symbol {
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
@@ -3769,9 +3776,9 @@ input[type="text"] {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
background: black;
color: #e6e6e6;
padding: 2px 5px;
@@ -4051,9 +4058,9 @@ input[type="text"] {
background-image: -moz-linear-gradient(#525252, #454545);
background-image: -webkit-linear-gradient(#525252, #454545);
background-image: linear-gradient(#525252, #454545);
- -moz-border-radius: 2px;
- -webkit-border-radius: 2px;
- border-radius: 2px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
@@ -4746,27 +4753,34 @@ input[type="text"] {
margin-top: -5%;
margin-left: -5%;
z-index: 2; }
+ /* line 53, ../sass/helpers/_wait-spinner.scss */
+ .t-wait-spinner.inline,
+ .wait-spinner.inline {
+ display: inline-block !important;
+ margin-right: 5px;
+ position: relative !important;
+ vertical-align: middle; }
-/* line 55, ../sass/helpers/_wait-spinner.scss */
+/* line 61, ../sass/helpers/_wait-spinner.scss */
.l-wait-spinner-holder {
pointer-events: none;
position: absolute; }
- /* line 59, ../sass/helpers/_wait-spinner.scss */
+ /* line 65, ../sass/helpers/_wait-spinner.scss */
.l-wait-spinner-holder.align-left .t-wait-spinner {
left: 0;
margin-left: 0; }
- /* line 64, ../sass/helpers/_wait-spinner.scss */
+ /* line 70, ../sass/helpers/_wait-spinner.scss */
.l-wait-spinner-holder.full-size {
display: inline-block;
height: 100%;
width: 100%; }
- /* line 67, ../sass/helpers/_wait-spinner.scss */
+ /* line 73, ../sass/helpers/_wait-spinner.scss */
.l-wait-spinner-holder.full-size .t-wait-spinner {
top: 0;
margin-top: 0;
padding: 30%; }
-/* line 76, ../sass/helpers/_wait-spinner.scss */
+/* line 82, ../sass/helpers/_wait-spinner.scss */
.treeview .wait-spinner {
display: block;
position: absolute;
@@ -4786,6 +4800,27 @@ input[type="text"] {
top: 2px;
left: 0; }
+/* line 91, ../sass/helpers/_wait-spinner.scss */
+.wait-spinner.sm {
+ 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(0, 153, 204, 0.25);
+ border-top-color: #0099cc;
+ border-style: solid;
+ border-width: 0.25em;
+ border-radius: 100%;
+ height: 13px;
+ width: 13px;
+ margin-left: 0 !important;
+ margin-top: 0 !important;
+ padding: 0 !important;
+ top: 0;
+ left: 0; }
+
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
@@ -4990,6 +5025,18 @@ input[type="text"] {
height: 100%;
width: 100%; }
+/* Styles for messages */
+/* line 4, ../sass/_messages.scss */
+.message.block {
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ border-radius: 2px;
+ padding: 10px; }
+/* line 8, ../sass/_messages.scss */
+.message.error {
+ background-color: rgba(255, 60, 0, 0.3);
+ color: #ff8a66; }
+
/* line 5, ../sass/_initialization.scss */
.browse-mode .split-layout .split-pane-component.pane.left {
width: 15%; }
@@ -5029,3 +5076,31 @@ input[type="text"] {
/* line 32, ../sass/_hide-non-functional.scss */
.browse-mode .browse-area.holder {
top: 10px; }
+
+/* Styles for sub-dividing views generically */
+/* line 3, ../sass/_views.scss */
+.l-view-section {
+ overflow: hidden;
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ width: auto;
+ height: auto;
+ font-size: 0.8rem; }
+ /* line 6, ../sass/_views.scss */
+ .l-view-section h2 {
+ color: #fff;
+ margin-bottom: 5px; }
+ /* line 10, ../sass/_views.scss */
+ .l-view-section.fixed {
+ font-size: 0.8em; }
+ /* line 13, ../sass/_views.scss */
+ .l-view-section.scrolling {
+ overflow: auto; }
+ /* line 16, ../sass/_views.scss */
+ .l-view-section .controls,
+ .l-view-section label,
+ .l-view-section .inline-block {
+ display: inline-block; }
diff --git a/platform/commonUI/general/res/css/tree.css b/platform/commonUI/general/res/css/tree.css
index e7400b5d04..8f3ac4871a 100644
--- a/platform/commonUI/general/res/css/tree.css
+++ b/platform/commonUI/general/res/css/tree.css
@@ -69,6 +69,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
+/*********************************************** FORM ELEMENTS */
/*
@mixin invokeMenu($baseColor: $colorBodyFg) {
$c: $baseColor;
@@ -103,7 +104,7 @@
ul.tree {
margin: 0;
padding: 0; }
- /* line 276, ../sass/_mixins.scss */
+ /* line 308, ../sass/_mixins.scss */
ul.tree li {
list-style-type: none;
margin: 0;
diff --git a/platform/commonUI/general/res/fonts/symbols/iconmoon.io-WTD-Symbols-v2.0.json b/platform/commonUI/general/res/fonts/symbols/icomoon.io-WTD-symbols-project.json
similarity index 99%
rename from platform/commonUI/general/res/fonts/symbols/iconmoon.io-WTD-Symbols-v2.0.json
rename to platform/commonUI/general/res/fonts/symbols/icomoon.io-WTD-symbols-project.json
index e2215bed12..502ce67f79 100644
--- a/platform/commonUI/general/res/fonts/symbols/iconmoon.io-WTD-Symbols-v2.0.json
+++ b/platform/commonUI/general/res/fonts/symbols/icomoon.io-WTD-symbols-project.json
@@ -1,19 +1,59 @@
{
"metadata": {
- "name": "WTD Symbols v2.",
- "lastOpened": 1435765696898,
- "created": 1435764071891
+ "name": "WTD Symbols v2.1",
+ "lastOpened": 1439844340068,
+ "created": 1439844318831
},
"iconSets": [
{
"selection": [
+ {
+ "order": 77,
+ "id": 83,
+ "prevSize": 32,
+ "code": 58881,
+ "name": "icon-datatable",
+ "tempChar": ""
+ },
+ {
+ "order": 78,
+ "id": 82,
+ "prevSize": 32,
+ "code": 58882,
+ "name": "icon-tabular-scrolling",
+ "tempChar": ""
+ },
+ {
+ "order": 79,
+ "id": 81,
+ "prevSize": 32,
+ "code": 58884,
+ "name": "icon-tabular",
+ "tempChar": ""
+ },
+ {
+ "order": 80,
+ "id": 80,
+ "prevSize": 32,
+ "code": 58885,
+ "name": "icon-calendar",
+ "tempChar": ""
+ },
+ {
+ "order": 81,
+ "id": 78,
+ "prevSize": 32,
+ "code": 58886,
+ "name": "icon-paint-bucket",
+ "tempChar": ""
+ },
{
"order": 1,
"id": 75,
"prevSize": 32,
"code": 123,
"name": "icon-pointer-left",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 3,
@@ -21,7 +61,7 @@
"prevSize": 32,
"code": 125,
"name": "icon-pointer-right",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 4,
@@ -29,7 +69,7 @@
"prevSize": 32,
"code": 80,
"name": "icon-person",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 5,
@@ -37,7 +77,7 @@
"prevSize": 32,
"code": 232,
"name": "icon-chain-links",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 6,
@@ -45,7 +85,7 @@
"prevSize": 32,
"code": 115,
"name": "icon-database-in-brackets",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 7,
@@ -53,7 +93,7 @@
"prevSize": 32,
"code": 114,
"name": "icon-refresh",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 8,
@@ -61,7 +101,7 @@
"prevSize": 32,
"code": 108,
"name": "icon-lock",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 9,
@@ -69,7 +109,7 @@
"prevSize": 32,
"code": 51,
"name": "icon-box-with-dashed-lines",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 10,
@@ -77,7 +117,7 @@
"prevSize": 32,
"code": 58880,
"name": "icon-box-with-arrow-cursor",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 11,
@@ -85,7 +125,7 @@
"prevSize": 32,
"code": 65,
"name": "icon-activity-mode",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 12,
@@ -93,7 +133,7 @@
"prevSize": 32,
"code": 97,
"name": "icon-activity",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 13,
@@ -101,7 +141,7 @@
"prevSize": 32,
"code": 33,
"name": "icon-alert-rect",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 14,
@@ -109,7 +149,7 @@
"prevSize": 32,
"code": 58883,
"name": "icon-alert-triangle",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 15,
@@ -117,7 +157,7 @@
"prevSize": 32,
"code": 238,
"name": "icon-arrow-double-down",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 16,
@@ -125,7 +165,7 @@
"prevSize": 32,
"code": 235,
"name": "icon-arrow-double-up",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 2,
@@ -133,7 +173,7 @@
"prevSize": 32,
"code": 118,
"name": "icon-arrow-down",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 19,
@@ -141,7 +181,7 @@
"prevSize": 32,
"code": 60,
"name": "icon-arrow-left",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 20,
@@ -149,7 +189,7 @@
"prevSize": 32,
"code": 62,
"name": "icon-arrow-right",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 21,
@@ -157,7 +197,7 @@
"prevSize": 32,
"code": 236,
"name": "icon-arrow-tall-down",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 22,
@@ -165,7 +205,7 @@
"prevSize": 32,
"code": 237,
"name": "icon-arrow-tall-up",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 23,
@@ -173,7 +213,7 @@
"prevSize": 32,
"code": 94,
"name": "icon-arrow-up",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 24,
@@ -181,7 +221,7 @@
"prevSize": 32,
"code": 73,
"name": "icon-arrows-out",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 25,
@@ -189,7 +229,7 @@
"prevSize": 32,
"code": 58893,
"name": "icon-arrows-right-left",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 33,
@@ -197,7 +237,7 @@
"prevSize": 32,
"code": 53,
"name": "icon-arrows-up-down",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 26,
@@ -205,7 +245,7 @@
"prevSize": 32,
"code": 42,
"name": "icon-asterisk",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 27,
@@ -213,7 +253,7 @@
"prevSize": 32,
"code": 72,
"name": "icon-autoflow-tabular",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 28,
@@ -221,7 +261,7 @@
"prevSize": 32,
"code": 224,
"name": "icon-box-round-corners",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 29,
@@ -229,7 +269,7 @@
"prevSize": 32,
"code": 50,
"name": "icon-check",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 30,
@@ -237,7 +277,7 @@
"prevSize": 32,
"code": 67,
"name": "icon-clock",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 31,
@@ -245,7 +285,7 @@
"prevSize": 32,
"code": 46,
"name": "icon-connectivity",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 32,
@@ -253,7 +293,7 @@
"prevSize": 32,
"code": 100,
"name": "icon-database-query",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 17,
@@ -261,7 +301,7 @@
"prevSize": 32,
"code": 68,
"name": "icon-database",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 35,
@@ -269,7 +309,7 @@
"prevSize": 32,
"code": 81,
"name": "icon-dictionary",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 36,
@@ -277,7 +317,7 @@
"prevSize": 32,
"code": 242,
"name": "icon-duplicate",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 37,
@@ -285,7 +325,7 @@
"prevSize": 32,
"code": 102,
"name": "icon-folder-new",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 38,
@@ -293,7 +333,7 @@
"prevSize": 32,
"code": 70,
"name": "icon-folder",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 39,
@@ -301,7 +341,7 @@
"prevSize": 32,
"code": 95,
"name": "icon-fullscreen-collapse",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 40,
@@ -309,7 +349,7 @@
"prevSize": 32,
"code": 122,
"name": "icon-fullscreen-expand",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 41,
@@ -317,7 +357,7 @@
"prevSize": 32,
"code": 71,
"name": "icon-gear",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 49,
@@ -325,7 +365,7 @@
"prevSize": 32,
"code": 227,
"name": "icon-image",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 42,
@@ -333,7 +373,7 @@
"prevSize": 32,
"code": 225,
"name": "icon-layers",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 43,
@@ -341,7 +381,7 @@
"prevSize": 32,
"code": 76,
"name": "icon-layout",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 44,
@@ -349,7 +389,7 @@
"prevSize": 32,
"code": 226,
"name": "icon-line-horz",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 75,
@@ -357,7 +397,7 @@
"prevSize": 32,
"code": 244,
"name": "icon-link",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 46,
@@ -365,7 +405,7 @@
"prevSize": 32,
"code": 88,
"name": "icon-magnify-in",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 47,
@@ -373,7 +413,7 @@
"prevSize": 32,
"code": 89,
"name": "icon-magnify-out",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 48,
@@ -381,7 +421,7 @@
"prevSize": 32,
"code": 77,
"name": "icon-magnify",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 34,
@@ -389,7 +429,7 @@
"prevSize": 32,
"code": 109,
"name": "icon-menu",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 50,
@@ -397,7 +437,7 @@
"prevSize": 32,
"code": 243,
"name": "icon-move",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 51,
@@ -405,7 +445,7 @@
"prevSize": 32,
"code": 121,
"name": "icon-new-window",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 52,
@@ -413,7 +453,7 @@
"prevSize": 32,
"code": 111,
"name": "icon-object",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 73,
@@ -421,7 +461,7 @@
"prevSize": 32,
"code": 63,
"name": "icon-object-unknown",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 53,
@@ -429,7 +469,7 @@
"prevSize": 32,
"code": 86,
"name": "icon-packet",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 54,
@@ -437,7 +477,7 @@
"prevSize": 32,
"code": 234,
"name": "icon-page",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 55,
@@ -445,7 +485,7 @@
"prevSize": 32,
"code": 241,
"name": "icon-pause",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 56,
@@ -453,7 +493,7 @@
"prevSize": 32,
"code": 112,
"name": "icon-pencil",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 65,
@@ -461,7 +501,7 @@
"prevSize": 32,
"code": 79,
"name": "icon-people",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 57,
@@ -469,7 +509,7 @@
"prevSize": 32,
"code": 239,
"name": "icon-play",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 58,
@@ -477,7 +517,7 @@
"prevSize": 32,
"code": 233,
"name": "icon-plot-resource",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 59,
@@ -485,7 +525,7 @@
"prevSize": 32,
"code": 43,
"name": "icon-plus",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 60,
@@ -493,7 +533,7 @@
"prevSize": 32,
"code": 45,
"name": "icon-minus",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 61,
@@ -501,7 +541,7 @@
"prevSize": 32,
"code": 54,
"name": "icon-sine",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 62,
@@ -509,7 +549,7 @@
"prevSize": 32,
"code": 228,
"name": "icon-T",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 63,
@@ -517,7 +557,7 @@
"prevSize": 32,
"code": 116,
"name": "icon-telemetry-panel",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 64,
@@ -525,7 +565,7 @@
"prevSize": 32,
"code": 84,
"name": "icon-telemetry",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 18,
@@ -533,7 +573,7 @@
"prevSize": 32,
"code": 246,
"name": "icon-thumbs-strip",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 67,
@@ -541,7 +581,7 @@
"prevSize": 32,
"code": 83,
"name": "icon-timeline",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 68,
@@ -549,7 +589,7 @@
"prevSize": 32,
"code": 245,
"name": "icon-timer",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 69,
@@ -557,7 +597,7 @@
"prevSize": 32,
"code": 90,
"name": "icon-trash",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 70,
@@ -565,7 +605,7 @@
"prevSize": 32,
"code": 229,
"name": "icon-two-parts-both",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 71,
@@ -573,7 +613,7 @@
"prevSize": 32,
"code": 231,
"name": "icon-two-parts-one-only",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 72,
@@ -581,7 +621,7 @@
"prevSize": 32,
"code": 120,
"name": "icon-x-heavy",
- "tempChar": ""
+ "tempChar": ""
},
{
"order": 66,
@@ -589,7 +629,7 @@
"prevSize": 32,
"code": 58946,
"name": "icon-x",
- "tempChar": ""
+ "tempChar": ""
}
],
"id": 2,
@@ -604,6 +644,182 @@
"height": 1024,
"prevSize": 32,
"icons": [
+ {
+ "id": 83,
+ "paths": [
+ "M1024 192c0 106.039-229.23 192-512 192s-512-85.961-512-192c0-106.039 229.23-192 512-192s512 85.961 512 192z",
+ "M512 512c-282.8 0-512-86-512-192v512c0 106 229.2 192 512 192s512-86 512-192v-512c0 106-229.2 192-512 192zM896 575v256c-36.6 15.6-79.8 28.8-128 39.4v-256c48.2-10.6 91.4-23.8 128-39.4zM256 614.4v256c-48.2-10.4-91.4-23.8-128-39.4v-256c36.6 15.6 79.8 28.8 128 39.4zM384 890v-256c41 4 83.8 6 128 6s87-2.2 128-6v256c-41 4-83.8 6-128 6s-87-2.2-128-6z"
+ ],
+ "attrs": [
+ {
+ "fill": "rgb(6,161,75)",
+ "opacity": 1
+ },
+ {
+ "fill": "rgb(6,161,75)",
+ "opacity": 1
+ }
+ ],
+ "isMulticolor": false,
+ "grid": 0,
+ "tags": [
+ "icon-datatable"
+ ],
+ "colorPermutations": {
+ "125525525516161751": [
+ 1,
+ 1
+ ]
+ }
+ },
+ {
+ "id": 82,
+ "paths": [
+ "M64 0c-35.2 0-64 28.8-64 64v192h448v-256h-384z",
+ "M1024 256v-192c0-35.2-28.8-64-64-64h-384v256h448z",
+ "M0 384v192c0 35.2 28.8 64 64 64h384v-256h-448z",
+ "M960 640c35.2 0 64-28.8 64-64v-192h-448v256h384z",
+ "M512 1024l-256-256h512z"
+ ],
+ "attrs": [
+ {
+ "fill": "rgb(6,161,75)",
+ "opacity": 1
+ },
+ {
+ "fill": "rgb(6,161,75)",
+ "opacity": 1
+ },
+ {
+ "fill": "rgb(6,161,75)",
+ "opacity": 1
+ },
+ {
+ "fill": "rgb(6,161,75)",
+ "opacity": 1
+ },
+ {
+ "fill": "rgb(6,161,75)",
+ "opacity": 1
+ }
+ ],
+ "isMulticolor": false,
+ "grid": 0,
+ "tags": [
+ "icon-tabular-scrolling"
+ ],
+ "colorPermutations": {
+ "125525525516161751": [
+ 1,
+ 1,
+ 1,
+ 1,
+ 1
+ ]
+ }
+ },
+ {
+ "id": 81,
+ "paths": [
+ "M0 64v192h448v-256h-384c-35.2 0-64 28.8-64 64z",
+ "M960 0h-384v256h448v-192c0-35.2-28.8-64-64-64z",
+ "M576 384h448v256h-448v-256z",
+ "M0 384h448v256h-448v-256z",
+ "M0 960c0 35.2 28.8 64 64 64h384v-256h-448v192z",
+ "M576 1024h384c35.2 0 64-28.8 64-64v-192h-448v256z"
+ ],
+ "attrs": [
+ {
+ "fill": "#000",
+ "opacity": 1
+ },
+ {
+ "fill": "#000",
+ "opacity": 1
+ },
+ {
+ "fill": "#000",
+ "opacity": 1
+ },
+ {
+ "fill": "#000",
+ "opacity": 1
+ },
+ {
+ "fill": "#000",
+ "opacity": 1
+ },
+ {
+ "fill": "#000",
+ "opacity": 1
+ }
+ ],
+ "isMulticolor": false,
+ "grid": 0,
+ "tags": [
+ "icon-tabular"
+ ],
+ "colorPermutations": {
+ "125525525516161751": [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "id": 80,
+ "paths": [
+ "M896 0h-768c-70.4 0-128 57.6-128 128v768c0 70.4 57.6 128 128 128h768c70.4 0 128-57.6 128-128v-768c0-70.4-57.6-128-128-128zM640 448h-256v-192h256v192zM384 512h256v192h-256v-192zM320 704h-256v-192h256v192zM320 256v192h-256v-192h256zM128 960c-17 0-33-6.6-45.2-18.8s-18.8-28.2-18.8-45.2v-128h256v192h-192zM384 960v-192h256v192h-256zM960 896c0 17-6.6 33-18.8 45.2s-28.2 18.8-45.2 18.8h-192v-192h256v128zM960 704h-256v-192h256v192zM960 448h-256v-192h256v192z"
+ ],
+ "attrs": [
+ {
+ "fill": "rgb(6,161,75)",
+ "opacity": 1
+ }
+ ],
+ "isMulticolor": false,
+ "grid": 0,
+ "tags": [
+ "icon-calendar"
+ ],
+ "colorPermutations": {
+ "125525525516161751": [
+ 1
+ ]
+ }
+ },
+ {
+ "id": 78,
+ "paths": [
+ "M896 640c0 0-130 188-128 256 2 70.6 57.4 128 128 128s126-57.4 128-128c2-68-128-256-128-256z",
+ "M449 129l0.2-64.8c0-35.4-28.4-64-63.8-64.2 0 0-0.2 0-0.2 0-35.2 0-63.8 28.6-64 63.8l-0.6 190.8-294 292.6c-50 50-12.4 215.2 112.4 340s290 162.4 340 112.4l417-423.6-447-447zM384 640c-70.6 0-128-57.4-128-128 0-47.4 25.8-89 64.4-111l-0.4 110.8c0 35.4 28.4 64 63.8 64.2 0 0 0.2 0 0.2 0 35.2 0 63.8-28.6 64-63.8l0.4-110.8c38 22.2 63.6 63.4 63.6 110.6 0 70.6-57.4 128-128 128z"
+ ],
+ "attrs": [
+ {
+ "fill": "rgb(6,161,75)",
+ "opacity": 1
+ },
+ {
+ "fill": "rgb(6,161,75)",
+ "opacity": 1
+ }
+ ],
+ "isMulticolor": false,
+ "grid": 0,
+ "tags": [
+ "icon-paint-bucket"
+ ],
+ "colorPermutations": {
+ "125525525516161751": [
+ 1,
+ 1
+ ]
+ }
+ },
{
"id": 75,
"paths": [
@@ -1767,7 +1983,24 @@
]
}
],
- "invisible": false
+ "invisible": false,
+ "colorThemes": [
+ [
+ [
+ 0,
+ 0,
+ 0,
+ 1
+ ],
+ [
+ 6,
+ 161,
+ 75,
+ 1
+ ]
+ ]
+ ],
+ "colorThemeIdx": 0
},
{
"selection": [
@@ -14510,7 +14743,8 @@
"selector": "class",
"classSelector": ".ui-symbol",
"showMetrics": true,
- "showMetadata": true
+ "showMetadata": true,
+ "embed": false
},
"imagePref": {
"prefix": "icon-",
diff --git a/platform/commonUI/general/res/fonts/symbols/wtdsymbols.eot b/platform/commonUI/general/res/fonts/symbols/wtdsymbols.eot
index 278460b5a8..2f4f938076 100755
Binary files a/platform/commonUI/general/res/fonts/symbols/wtdsymbols.eot and b/platform/commonUI/general/res/fonts/symbols/wtdsymbols.eot differ
diff --git a/platform/commonUI/general/res/fonts/symbols/wtdsymbols.svg b/platform/commonUI/general/res/fonts/symbols/wtdsymbols.svg
index 9c9d712d2d..d31a879fc3 100755
--- a/platform/commonUI/general/res/fonts/symbols/wtdsymbols.svg
+++ b/platform/commonUI/general/res/fonts/symbols/wtdsymbols.svg
@@ -6,78 +6,83 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/platform/commonUI/general/res/fonts/symbols/wtdsymbols.ttf b/platform/commonUI/general/res/fonts/symbols/wtdsymbols.ttf
index b113a531a4..37af03fa79 100755
Binary files a/platform/commonUI/general/res/fonts/symbols/wtdsymbols.ttf and b/platform/commonUI/general/res/fonts/symbols/wtdsymbols.ttf differ
diff --git a/platform/commonUI/general/res/fonts/symbols/wtdsymbols.woff b/platform/commonUI/general/res/fonts/symbols/wtdsymbols.woff
index 5989698d98..c93e44215c 100755
Binary files a/platform/commonUI/general/res/fonts/symbols/wtdsymbols.woff and b/platform/commonUI/general/res/fonts/symbols/wtdsymbols.woff differ
diff --git a/platform/commonUI/general/res/sass/_constants.scss b/platform/commonUI/general/res/sass/_constants.scss
index 3051dc616c..22518172da 100644
--- a/platform/commonUI/general/res/sass/_constants.scss
+++ b/platform/commonUI/general/res/sass/_constants.scss
@@ -29,7 +29,7 @@ $interiorMargin: 5px;
$interiorMarginLg: $interiorMargin * 2;
$interiorMarginSm: 3px;
$basicCr: 2px;
-$controlCr: 2px;
+$controlCr: 3px;
$smallCr: 2px;
$badgeW: 35px;
@@ -84,6 +84,7 @@ $tabularColorBodyBg: darken($colorBodyBg, 10%);
$tabularColorBodyFg: lighten($tabularColorBodyBg, 40%);
$tabularColorHeaderBg: lighten($colorBodyBg, 10%);
$tabularColorHeaderFg: lighten($tabularColorHeaderBg, 40%);
+$tabularColorHeaderBorder: $colorBodyBg;
/************************** RATIOS */
$ltGamma: 20%;
@@ -115,9 +116,9 @@ $colorItemTreeIcon: $colorKey;
$colorItemTreeIconHover: lighten($colorItemTreeIcon, 20%);
$colorItemTreeVCHover: $colorAlt1;
// Tabular
-$tabularHeaderH: 18px;
+$tabularHeaderH: 22px; //18px
$tabularTdPadLR: $itemPadLR;
-$tabularTdPadTB: 2px;
+$tabularTdPadTB: 3px;
// Imagery
$imageMainControlBarH: 22px;
$imageThumbsD: 120px;
@@ -141,7 +142,6 @@ $reqSymbolM: $interiorMargin * 2;
$reqSymbolFontSize: 0.7em;
/************************** CONTROLS */
-$controlCr: $basicCr;
$controlDisabledOpacity: 0.3;
$formLabelW: 20%;
$formInputH: 22px;
diff --git a/platform/commonUI/general/res/sass/_global.scss b/platform/commonUI/general/res/sass/_global.scss
index 3c28d54c7d..94fe8e151c 100644
--- a/platform/commonUI/general/res/sass/_global.scss
+++ b/platform/commonUI/general/res/sass/_global.scss
@@ -50,6 +50,11 @@ input, textarea {
font-family: Helvetica, Arial, sans-serif;
}
+input[type="text"] {
+ vertical-align: baseline;
+ padding: 3px 5px !important;
+}
+
h1, h2, h3 {
margin: 0;
}
diff --git a/platform/commonUI/general/res/sass/_main.scss b/platform/commonUI/general/res/sass/_main.scss
index d56c55aca5..5866aee700 100644
--- a/platform/commonUI/general/res/sass/_main.scss
+++ b/platform/commonUI/general/res/sass/_main.scss
@@ -34,7 +34,6 @@
@import "fixed-position";
@import "about";
@import "text";
-@import "badges";
@import "icons";
@import "limits";
@import "data-status";
@@ -49,7 +48,6 @@
@import "edit/editor";
@import "features/imagery";
@import "features/time-display";
-@import "forms/mixins";
@import "forms/elems";
@import "forms/validation";
@import "forms/text-input";
@@ -70,5 +68,7 @@
@import "properties";
@import "autoflow";
@import "iframe";
+@import "messages";
@import "initialization";
@import "hide-non-functional";
+@import "views";
diff --git a/platform/commonUI/general/res/sass/_messages.scss b/platform/commonUI/general/res/sass/_messages.scss
new file mode 100644
index 0000000000..db4de4c946
--- /dev/null
+++ b/platform/commonUI/general/res/sass/_messages.scss
@@ -0,0 +1,12 @@
+/* Styles for messages */
+
+.message {
+ &.block {
+ @include border-radius($basicCr);
+ padding: $interiorMarginLg;
+ }
+ &.error {
+ background-color: rgba($colorAlert,0.3);
+ color: lighten($colorAlert, 20%);
+ }
+}
\ No newline at end of file
diff --git a/platform/commonUI/general/res/sass/_mixins.scss b/platform/commonUI/general/res/sass/_mixins.scss
index dc37d94fb6..08dd72cd00 100644
--- a/platform/commonUI/general/res/sass/_mixins.scss
+++ b/platform/commonUI/general/res/sass/_mixins.scss
@@ -259,6 +259,38 @@
@include text-shadow(rgba(black, $sVal) 0 3px 7px);
}
+/*********************************************** FORM ELEMENTS */
+@mixin input-base($bg: $colorBodyBg, $fg: $colorBodyFg) {
+ @include appearance(none);
+ @include border-radius($controlCr);
+ @include box-sizing(border-box);
+ @include box-shadow(inset rgba(black, 0.65) 0 1px 4px);
+ // background: lighten($bg, 20%);
+ background: rgba(#fff, 0.1);
+ border: none;
+ //border-bottom: 1px solid rgba(#fff, 0.1);
+ color: lighten($fg, 20%);
+ outline: none;
+ &.error {
+ background: rgba(red, 0.5);
+ }
+}
+
+@mixin nice-input($bg: $colorBodyBg, $fg: $colorBodyFg) {
+ @include input-base($bg, $fg);
+ padding: 0 $interiorMarginSm;
+}
+
+@mixin nice-textarea($bg: $colorBodyBg, $fg: $colorBodyFg) {
+ @include input-base($bg, $fg);
+ padding: $interiorMargin;
+}
+
+@mixin subdued-input($bg: $colorBodyBg, $fg: $colorBodyFg) {
+ @include nice-input($bg, $fg);
+ background: lighten($bg, 3%);
+ border-bottom: 1px solid lighten($bg, 10%);
+}
/*
@mixin invokeMenu($baseColor: $colorBodyFg) {
diff --git a/platform/commonUI/general/res/sass/_views.scss b/platform/commonUI/general/res/sass/_views.scss
new file mode 100644
index 0000000000..ef83e3c29b
--- /dev/null
+++ b/platform/commonUI/general/res/sass/_views.scss
@@ -0,0 +1,21 @@
+/* Styles for sub-dividing views generically */
+
+.l-view-section {
+ @include absPosDefault(0);
+ font-size: 0.8rem;
+ h2 {
+ color: #fff;
+ margin-bottom: $interiorMargin;
+ }
+ &.fixed {
+ font-size: 0.8em;
+ }
+ &.scrolling {
+ overflow: auto;
+ }
+ .controls,
+ label,
+ .inline-block {
+ display: inline-block;
+ }
+}
\ No newline at end of file
diff --git a/platform/commonUI/general/res/sass/forms/_elems.scss b/platform/commonUI/general/res/sass/forms/_elems.scss
index a47cdc2484..9a2adab2e3 100644
--- a/platform/commonUI/general/res/sass/forms/_elems.scss
+++ b/platform/commonUI/general/res/sass/forms/_elems.scss
@@ -86,13 +86,6 @@
}
}
- input[type="text"] {
- height: $formInputH;
- line-height: $formInputH;
- margin-top: -4px;
- vertical-align: baseline;
- }
-
.l-med input[type="text"] {
width: 200px;
}
diff --git a/platform/commonUI/general/res/sass/forms/_mixins.scss b/platform/commonUI/general/res/sass/forms/_mixins.scss
index fae98a588f..e80999174c 100644
--- a/platform/commonUI/general/res/sass/forms/_mixins.scss
+++ b/platform/commonUI/general/res/sass/forms/_mixins.scss
@@ -23,11 +23,11 @@
@include appearance(none);
@include border-radius($controlCr);
@include box-sizing(border-box);
- @include box-shadow(inset rgba(black, 0.5) 0 1px 5px);
+ @include box-shadow(inset rgba(black, 0.65) 0 1px 4px);
// background: lighten($bg, 20%);
background: rgba(#fff, 0.1);
border: none;
- border-bottom: 1px solid rgba(#fff, 0.1);
+ //border-bottom: 1px solid rgba(#fff, 0.1);
color: lighten($fg, 20%);
outline: none;
&.error {
diff --git a/platform/commonUI/general/res/sass/helpers/_wait-spinner.scss b/platform/commonUI/general/res/sass/helpers/_wait-spinner.scss
index fafae5e9ea..f80c1f1971 100644
--- a/platform/commonUI/general/res/sass/helpers/_wait-spinner.scss
+++ b/platform/commonUI/general/res/sass/helpers/_wait-spinner.scss
@@ -50,6 +50,12 @@
margin-top: $d / -1;
margin-left: $d / -1;
z-index: 2;
+ &.inline {
+ display: inline-block !important;
+ margin-right: $interiorMargin;
+ position: relative !important;
+ vertical-align: middle;
+ }
}
.l-wait-spinner-holder {
@@ -80,4 +86,14 @@
margin: 0 !important;
padding: 0 !important;
top: 2px; left: 0;
+}
+
+.wait-spinner.sm {
+ $d: 13px;
+ @include wait-spinner(0.25em, $colorKey);
+ height: $d; width: $d;
+ margin-left: 0 !important;
+ margin-top: 0 !important;
+ padding: 0 !important;
+ top: 0; left: 0;
}
\ No newline at end of file
diff --git a/platform/commonUI/general/res/sass/lists/_tabular.scss b/platform/commonUI/general/res/sass/lists/_tabular.scss
index 0b449baccf..629cac9d1a 100644
--- a/platform/commonUI/general/res/sass/lists/_tabular.scss
+++ b/platform/commonUI/general/res/sass/lists/_tabular.scss
@@ -24,13 +24,14 @@
height: 100%;
}
-.tabular {
+.tabular,
+table {
@include box-sizing(border-box);
border-spacing: 0;
border-collapse: collapse;
color: #fff;
display: table;
- font-size: 0.75em;
+ font-size: 0.75rem;
position: relative;
//height: 100%; MOVED
width: 100%;
@@ -41,19 +42,7 @@
//table-layout: fixed; MOVED
}
thead, .thead {
- //width: calc(100% - 10px); MOVED
- tr, .tr {
- height: $tabularHeaderH;
- }
- &:before {
- content: "";
- display: block;
- z-index: 0;
- position: absolute;
- width: 100%;
- height: $tabularHeaderH;
- background: rgba(#fff, 0.15);
- }
+ border-bottom: 1px solid $tabularColorHeaderBorder;
}
tbody, .tbody {
//@include absPosDefault(0); MOVED
@@ -72,14 +61,21 @@
&:first-child .td {
border-top: none;
}
+ &.group-header {
+ td, .td {
+ $d: 5%;
+ background-color: darken($tabularColorHeaderBg, $d);
+ color: darken($tabularColorHeaderFg, $d);
+ }
+ }
th, .th, td, .td {
display: table-cell;
}
th, .th {
- border: none;
- border-left: 1px solid $tabularColorBorder;
+ background-color: $tabularColorHeaderBg;
+ border-left: 1px solid $tabularColorHeaderBorder;
color: $tabularColorHeaderFg;
- padding: 0 $tabularTdPadLR;
+ padding: $tabularTdPadLR $tabularTdPadLR;
white-space: nowrap;
vertical-align: middle; // This is crucial to hiding f**king 4px height injected by browser by default
&:first-child {
@@ -100,10 +96,11 @@
}
}
td, .td {
- border-top: 1px solid $tabularColorBorder;
- min-width: 110px;
+ border-bottom: 1px solid $tabularColorBorder;
+ min-width: 20px;
color: $colorTelemFresh;
padding: $tabularTdPadTB $tabularTdPadLR;
+ word-wrap: break-word;
vertical-align: top;
&.numeric {
text-align: right;
@@ -119,9 +116,20 @@
}
}
&.filterable {
+ thead, .thead {
+ tr.s-filters, .tr.s-filters {
+ th, .th {
+ //border-left: none;
+ }
+ }
+ }
tbody, .tbody {
top: $tabularHeaderH * 2;
}
+ input[type="text"] {
+ @include box-sizing(border-box);
+ width: 100%; //50px;
+ }
}
&.fixed-header {
@@ -133,6 +141,15 @@
}
thead, .thead {
width: calc(100% - 10px);
+ &:before {
+ content: "";
+ display: block;
+ z-index: 0;
+ position: absolute;
+ width: 100%;
+ height: $tabularHeaderH;
+ background: rgba(#fff, 0.15);
+ }
}
tbody, .tbody {
@include absPosDefault(0);
diff --git a/platform/persistence/elastic/src/ElasticsearchSearchProvider.js b/platform/persistence/elastic/src/ElasticsearchSearchProvider.js
new file mode 100644
index 0000000000..af13628af9
--- /dev/null
+++ b/platform/persistence/elastic/src/ElasticsearchSearchProvider.js
@@ -0,0 +1,213 @@
+/*****************************************************************************
+ * 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*/
+
+/**
+ * Module defining ElasticsearchSearchProvider. Created by shale on 07/16/2015.
+ * This is not currently included in the bundle definition.
+ */
+define(
+ [],
+ function () {
+ "use strict";
+
+ // JSLint doesn't like underscore-prefixed properties,
+ // so hide them here.
+ var ID = "_id",
+ SCORE = "_score",
+ DEFAULT_MAX_RESULTS = 100;
+
+ /**
+ * A search service which searches through domain objects in
+ * the filetree using ElasticSearch.
+ *
+ * @constructor
+ * @param $http Angular's $http service, for working with urls.
+ * @param {ObjectService} objectService the service from which
+ * domain objects can be gotten.
+ * @param ROOT the constant ELASTIC_ROOT which allows us to
+ * interact with ElasticSearch.
+ */
+ function ElasticsearchSearchProvider($http, objectService, ROOT) {
+
+ // Add the fuzziness operator to the search term
+ function addFuzziness(searchTerm, editDistance) {
+ if (!editDistance) {
+ editDistance = '';
+ }
+
+ return searchTerm.split(' ').map(function (s) {
+ // Don't add fuzziness for quoted strings
+ if (s.indexOf('"') !== -1) {
+ return s;
+ } else {
+ return s + '~' + editDistance;
+ }
+ }).join(' ');
+ }
+
+ // Currently specific to elasticsearch
+ function processSearchTerm(searchTerm) {
+ var spaceIndex;
+
+ // Cut out any extra spaces
+ while (searchTerm.substr(0, 1) === ' ') {
+ searchTerm = searchTerm.substring(1, searchTerm.length);
+ }
+ while (searchTerm.substr(searchTerm.length - 1, 1) === ' ') {
+ searchTerm = searchTerm.substring(0, searchTerm.length - 1);
+ }
+ spaceIndex = searchTerm.indexOf(' ');
+ while (spaceIndex !== -1) {
+ searchTerm = searchTerm.substring(0, spaceIndex) +
+ searchTerm.substring(spaceIndex + 1, searchTerm.length);
+ spaceIndex = searchTerm.indexOf(' ');
+ }
+
+ // Add fuzziness for completeness
+ searchTerm = addFuzziness(searchTerm);
+
+ return searchTerm;
+ }
+
+ // Processes results from the format that elasticsearch returns to
+ // a list of searchResult objects, then returns a result object
+ // (See documentation for query for object descriptions)
+ function processResults(rawResults, timestamp) {
+ var results = rawResults.data.hits.hits,
+ resultsLength = results.length,
+ ids = [],
+ scores = {},
+ searchResults = [],
+ i;
+
+ // Get the result objects' IDs
+ for (i = 0; i < resultsLength; i += 1) {
+ ids.push(results[i][ID]);
+ }
+
+ // Get the result objects' scores
+ for (i = 0; i < resultsLength; i += 1) {
+ scores[ids[i]] = results[i][SCORE];
+ }
+
+ // Get the domain objects from their IDs
+ return objectService.getObjects(ids).then(function (objects) {
+ var j,
+ id;
+
+ for (j = 0; j < resultsLength; j += 1) {
+ id = ids[j];
+
+ // Include items we can get models for
+ if (objects[id].getModel) {
+ // Format the results as searchResult objects
+ searchResults.push({
+ id: id,
+ object: objects[id],
+ score: scores[id]
+ });
+ }
+ }
+
+ return {
+ hits: searchResults,
+ total: rawResults.data.hits.total,
+ timedOut: rawResults.data.timed_out
+ };
+ });
+ }
+
+ // For documentation, see query below.
+ function query(searchTerm, timestamp, maxResults, timeout) {
+ var esQuery;
+
+ // Check to see if the user provided a maximum
+ // number of results to display
+ if (!maxResults) {
+ // Else, we provide a default value.
+ maxResults = DEFAULT_MAX_RESULTS;
+ }
+
+ // If the user input is empty, we want to have no search results.
+ if (searchTerm !== '' && searchTerm !== undefined) {
+ // Process the search term
+ searchTerm = processSearchTerm(searchTerm);
+
+ // Create the query to elasticsearch
+ esQuery = ROOT + "/_search/?q=" + searchTerm +
+ "&size=" + maxResults;
+ if (timeout) {
+ esQuery += "&timeout=" + timeout;
+ }
+
+ // Get the data...
+ return $http({
+ method: "GET",
+ url: esQuery
+ }).then(function (rawResults) {
+ // ...then process the data
+ return processResults(rawResults, timestamp);
+ }, function (err) {
+ // In case of error, return nothing. (To prevent
+ // infinite loading time.)
+ return {hits: [], total: 0};
+ });
+ } else {
+ return {hits: [], total: 0};
+ }
+ }
+
+ return {
+ /**
+ * Searches through the filetree for domain objects using a search
+ * term. This is done through querying elasticsearch. Returns a
+ * promise for a result object that has the format
+ * {hits: searchResult[], total: number, timedOut: boolean}
+ * where a searchResult has the format
+ * {id: string, object: domainObject, score: number}
+ *
+ * Notes:
+ * * The order of the results is from highest to lowest score,
+ * as elsaticsearch determines them to be.
+ * * Uses the fuzziness operator to get more results.
+ * * More about this search's behavior at
+ * https://www.elastic.co/guide/en/elasticsearch/reference/current/search-uri-request.html
+ *
+ * @param searchTerm The text input that is the query.
+ * @param timestamp The time at which this function was called.
+ * This timestamp is used as a unique identifier for this
+ * query and the corresponding results.
+ * @param maxResults (optional) The maximum number of results
+ * that this function should return.
+ * @param timeout (optional) The time after which the search should
+ * stop calculations and return partial results. Elasticsearch
+ * does not guarentee that this timeout will be strictly followed.
+ */
+ query: query
+ };
+ }
+
+
+ return ElasticsearchSearchProvider;
+ }
+);
\ No newline at end of file
diff --git a/platform/persistence/elastic/test/ElasticsearchSearchProviderSpec.js b/platform/persistence/elastic/test/ElasticsearchSearchProviderSpec.js
new file mode 100644
index 0000000000..1202ef77e6
--- /dev/null
+++ b/platform/persistence/elastic/test/ElasticsearchSearchProviderSpec.js
@@ -0,0 +1,115 @@
+/*****************************************************************************
+ * 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,jasmine*/
+
+/**
+ * SearchSpec. Created by shale on 07/31/2015.
+ */
+define(
+ ["../src/ElasticsearchSearchProvider"],
+ function (ElasticsearchSearchProvider) {
+ "use strict";
+
+ // JSLint doesn't like underscore-prefixed properties,
+ // so hide them here.
+ var ID = "_id",
+ SCORE = "_score";
+
+ describe("The ElasticSearch search provider ", function () {
+ var mockHttp,
+ mockHttpPromise,
+ mockObjectPromise,
+ mockObjectService,
+ mockDomainObject,
+ provider,
+ mockProviderResults;
+
+ beforeEach(function () {
+ mockHttp = jasmine.createSpy("$http");
+ mockHttpPromise = jasmine.createSpyObj(
+ "promise",
+ [ "then" ]
+ );
+ mockHttp.andReturn(mockHttpPromise);
+ // allow chaining of promise.then().catch();
+ mockHttpPromise.then.andReturn(mockHttpPromise);
+
+ mockObjectService = jasmine.createSpyObj(
+ "objectService",
+ [ "getObjects" ]
+ );
+ mockObjectPromise = jasmine.createSpyObj(
+ "promise",
+ [ "then" ]
+ );
+ mockObjectService.getObjects.andReturn(mockObjectPromise);
+
+ mockDomainObject = jasmine.createSpyObj(
+ "domainObject",
+ [ "getId", "getModel" ]
+ );
+
+ provider = new ElasticsearchSearchProvider(mockHttp, mockObjectService, "");
+ provider.query(' test "query" ', 0, undefined, 1000);
+ });
+
+ it("sends a query to ElasticSearch", function () {
+ expect(mockHttp).toHaveBeenCalled();
+ });
+
+ it("gets data from ElasticSearch", function () {
+ var data = {
+ hits: {
+ hits: [
+ {},
+ {}
+ ],
+ total: 0
+ },
+ timed_out: false
+ };
+ data.hits.hits[0][ID] = 1;
+ data.hits.hits[0][SCORE] = 1;
+ data.hits.hits[1][ID] = 2;
+ data.hits.hits[1][SCORE] = 2;
+
+ mockProviderResults = mockHttpPromise.then.mostRecentCall.args[0]({data: data});
+
+ expect(
+ mockObjectPromise.then.mostRecentCall.args[0]({
+ 1: mockDomainObject,
+ 2: mockDomainObject
+ }).hits.length
+ ).toEqual(2);
+ });
+
+ it("returns nothing for an empty string query", function () {
+ expect(provider.query("").hits).toEqual([]);
+ });
+
+ it("returns something when there is an ElasticSearch error", function () {
+ mockProviderResults = mockHttpPromise.then.mostRecentCall.args[1]();
+ expect(mockProviderResults).toBeDefined();
+ });
+ });
+ }
+);
\ No newline at end of file
diff --git a/platform/persistence/elastic/test/suite.json b/platform/persistence/elastic/test/suite.json
index cc8dc2ce0c..939244c089 100644
--- a/platform/persistence/elastic/test/suite.json
+++ b/platform/persistence/elastic/test/suite.json
@@ -1,4 +1,5 @@
[
"ElasticIndicator",
- "ElasticPersistenceProvider"
+ "ElasticPersistenceProvider",
+ "ElasticsearchSearchProvider"
]
diff --git a/platform/representation/src/actions/ContextMenuAction.js b/platform/representation/src/actions/ContextMenuAction.js
index 390531053e..67b48536c3 100644
--- a/platform/representation/src/actions/ContextMenuAction.js
+++ b/platform/representation/src/actions/ContextMenuAction.js
@@ -31,7 +31,7 @@ define(
var MENU_TEMPLATE = "" +
"",
dismissExistingMenu;
@@ -48,7 +48,7 @@ define(
* should be performed
*/
function ContextMenuAction($compile, $document, $window, $rootScope, actionContext) {
-
+
function perform() {
var winDim = [$window.innerWidth, $window.innerHeight],
eventCoors = [actionContext.event.pageX, actionContext.event.pageY],
@@ -62,7 +62,7 @@ define(
// Remove the context menu
function dismiss() {
menu.remove();
- body.off("click", dismiss);
+ body.off("mousedown", dismiss);
dismissExistingMenu = undefined;
}
@@ -92,20 +92,21 @@ define(
// Add the menu to the body
body.append(menu);
-
+
// Stop propagation so that clicks on the menu do not close the menu
menu.on('mousedown', function (event) {
event.stopPropagation();
});
-
+
// Dismiss the menu when body is clicked elsewhere
// ('mousedown' because 'click' breaks left-click context menus)
body.on('mousedown', dismiss);
+ menu.on('click', dismiss);
// Don't launch browser's context menu
actionContext.event.preventDefault();
}
-
+
return {
perform: perform
};
@@ -113,4 +114,4 @@ define(
return ContextMenuAction;
}
-);
\ No newline at end of file
+);
diff --git a/platform/representation/test/actions/ContextMenuActionSpec.js b/platform/representation/test/actions/ContextMenuActionSpec.js
index 73b877ddc3..03298162b4 100644
--- a/platform/representation/test/actions/ContextMenuActionSpec.js
+++ b/platform/representation/test/actions/ContextMenuActionSpec.js
@@ -69,7 +69,7 @@ define(
mockCompiledTemplate.andReturn(mockMenu);
mockDocument.find.andReturn(mockBody);
mockRootScope.$new.andReturn(mockScope);
-
+
mockActionContext = {key: 'menu', domainObject: mockDomainObject, event: mockEvent};
action = new ContextMenuAction(
@@ -118,9 +118,9 @@ define(
it("removes a menu when body is clicked", function () {
// Show the menu
action.perform();
-
+
// Verify precondition
- expect(mockBody.off).not.toHaveBeenCalled();
+ expect(mockBody.remove).not.toHaveBeenCalled();
// Find and fire body's mousedown listener
mockBody.on.calls.forEach(function (call) {
@@ -133,8 +133,29 @@ define(
expect(mockMenu.remove).toHaveBeenCalled();
// Listener should have been detached from body
- expect(mockBody.off).toHaveBeenCalled();
+ expect(mockBody.off).toHaveBeenCalledWith(
+ 'mousedown',
+ jasmine.any(Function)
+ );
+ });
+
+ it("removes a menu when it is clicked", function () {
+ // Show the menu
+ action.perform();
+
+ // Verify precondition
+ expect(mockMenu.remove).not.toHaveBeenCalled();
+
+ // Find and fire body's mousedown listener
+ mockMenu.on.calls.forEach(function (call) {
+ if (call.args[0] === 'click') {
+ call.args[1]();
+ }
+ });
+
+ // Menu should have been removed
+ expect(mockMenu.remove).toHaveBeenCalled();
});
});
}
-);
\ No newline at end of file
+);
diff --git a/platform/search/bundle.json b/platform/search/bundle.json
new file mode 100644
index 0000000000..6668022939
--- /dev/null
+++ b/platform/search/bundle.json
@@ -0,0 +1,33 @@
+{
+ "name": "Search",
+ "description": "Allows the user to search through the file tree.",
+ "extensions": {
+ "constants": [
+ {
+ "key": "GENERIC_SEARCH_ROOTS",
+ "value": [ "ROOT" ],
+ "priority": "fallback"
+ }
+ ],
+ "components": [
+ {
+ "provides": "searchService",
+ "type": "provider",
+ "implementation": "GenericSearchProvider.js",
+ "depends": [ "$q", "$timeout", "objectService", "workerService", "GENERIC_SEARCH_ROOTS" ]
+ },
+ {
+ "provides": "searchService",
+ "type": "aggregator",
+ "implementation": "SearchAggregator.js",
+ "depends": [ "$q" ]
+ }
+ ],
+ "workers": [
+ {
+ "key": "genericSearchWorker",
+ "scriptUrl": "GenericSearchWorker.js"
+ }
+ ]
+ }
+}
diff --git a/platform/search/src/GenericSearchProvider.js b/platform/search/src/GenericSearchProvider.js
new file mode 100644
index 0000000000..dae2cab9a9
--- /dev/null
+++ b/platform/search/src/GenericSearchProvider.js
@@ -0,0 +1,268 @@
+/*****************************************************************************
+ * 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*/
+
+/**
+ * Module defining GenericSearchProvider. Created by shale on 07/16/2015.
+ */
+define(
+ [],
+ function () {
+ "use strict";
+
+ var DEFAULT_MAX_RESULTS = 100,
+ DEFAULT_TIMEOUT = 1000,
+ stopTime;
+
+ /**
+ * A search service which searches through domain objects in
+ * the filetree without using external search implementations.
+ *
+ * @constructor
+ * @param $q Angular's $q, for promise consolidation.
+ * @param $timeout Angular's $timeout, for delayed function execution.
+ * @param {ObjectService} objectService The service from which
+ * domain objects can be gotten.
+ * @param {WorkerService} workerService The service which allows
+ * more easy creation of web workers.
+ * @param {GENERIC_SEARCH_ROOTS} ROOTS An array of the root
+ * domain objects' IDs.
+ */
+ function GenericSearchProvider($q, $timeout, objectService, workerService, ROOTS) {
+ var worker = workerService.run('genericSearchWorker'),
+ indexed = {},
+ pendingQueries = {};
+ // pendingQueries is a dictionary with the key value pairs st
+ // the key is the timestamp and the value is the promise
+
+ // Tell the web worker to add a domain object's model to its list of items.
+ function indexItem(domainObject) {
+ var message;
+
+ // undefined check
+ if (domainObject && domainObject.getModel) {
+ // Using model instead of whole domain object because
+ // it's a JSON object.
+ message = {
+ request: 'index',
+ model: domainObject.getModel(),
+ id: domainObject.getId()
+ };
+ worker.postMessage(message);
+ }
+ }
+
+ // Tell the worker to search for items it has that match this searchInput.
+ // Takes the searchInput, as well as a max number of results (will return
+ // less than that if there are fewer matches).
+ function workerSearch(searchInput, maxResults, timestamp, timeout) {
+ var message = {
+ request: 'search',
+ input: searchInput,
+ maxNumber: maxResults,
+ timestamp: timestamp,
+ timeout: timeout
+ };
+ worker.postMessage(message);
+ }
+
+ // Handles responses from the web worker. Namely, the results of
+ // a search request.
+ function handleResponse(event) {
+ var ids = [],
+ id;
+
+ // If we have the results from a search
+ if (event.data.request === 'search') {
+ // Convert the ids given from the web worker into domain objects
+ for (id in event.data.results) {
+ ids.push(id);
+ }
+ objectService.getObjects(ids).then(function (objects) {
+ var searchResults = [],
+ id;
+
+ // Create searchResult objects
+ for (id in objects) {
+ searchResults.push({
+ object: objects[id],
+ id: id,
+ score: event.data.results[id]
+ });
+ }
+
+ // Resove the promise corresponding to this
+ pendingQueries[event.data.timestamp].resolve({
+ hits: searchResults,
+ total: event.data.total,
+ timedOut: event.data.timedOut
+ });
+ });
+ }
+ }
+
+ worker.onmessage = handleResponse;
+
+ // Helper function for getItems(). Indexes the tree.
+ function indexItems(nodes) {
+ nodes.forEach(function (node) {
+ var id = node && node.getId && node.getId();
+
+ // If we have already indexed this item, stop here
+ if (indexed[id]) {
+ return;
+ }
+
+ // Index each item with the web worker
+ indexItem(node);
+ indexed[id] = true;
+
+
+ // If this node has children, index those
+ if (node && node.hasCapability && node.hasCapability('composition')) {
+ // Make sure that this is async, so doesn't block up page
+ $timeout(function () {
+ // Get the children...
+ node.useCapability('composition').then(function (children) {
+ $timeout(function () {
+ // ... then index the children
+ if (children.constructor === Array) {
+ indexItems(children);
+ } else {
+ indexItems([children]);
+ }
+ }, 0);
+ });
+ }, 0);
+ }
+
+ // Watch for changes to this item, in case it gets new children
+ if (node && node.hasCapability && node.hasCapability('mutation')) {
+ node.getCapability('mutation').listen(function (listener) {
+ if (listener && listener.composition) {
+ // If the node was mutated to have children, get the child domain objects
+ objectService.getObjects(listener.composition).then(function (objectsById) {
+ var objects = [],
+ id;
+
+ // Get each of the domain objects in objectsById
+ for (id in objectsById) {
+ objects.push(objectsById[id]);
+ }
+
+ indexItems(objects);
+ });
+ }
+ });
+ }
+ });
+ }
+
+ // Converts the filetree into a list
+ function getItems() {
+ // Aquire root objects
+ objectService.getObjects(ROOTS).then(function (objectsById) {
+ var objects = [],
+ id;
+
+ // Get each of the domain objects in objectsById
+ for (id in objectsById) {
+ objects.push(objectsById[id]);
+ }
+
+ // Index all of the roots' descendents
+ indexItems(objects);
+ });
+ }
+
+ // For documentation, see query below
+ function query(input, timestamp, maxResults, timeout) {
+ var terms = [],
+ searchResults = [],
+ defer = $q.defer();
+
+ // If the input is nonempty, do a search
+ if (input !== '' && input !== undefined) {
+
+ // Allow us to access this promise later to resolve it later
+ pendingQueries[timestamp] = defer;
+
+ // Check to see if the user provided a maximum
+ // number of results to display
+ if (!maxResults) {
+ // Else, we provide a default value
+ maxResults = DEFAULT_MAX_RESULTS;
+ }
+ // Similarly, check if timeout was provided
+ if (!timeout) {
+ timeout = DEFAULT_TIMEOUT;
+ }
+
+ // Send the query to the worker
+ workerSearch(input, maxResults, timestamp, timeout);
+
+ return defer.promise;
+ } else {
+ // Otherwise return an empty result
+ return {hits: [], total: 0};
+ }
+ }
+
+ // Index the tree's contents once at the beginning
+ getItems();
+
+ return {
+ /**
+ * Searches through the filetree for domain objects which match
+ * the search term. This function is to be used as a fallback
+ * in the case where other search services are not avaliable.
+ * Returns a promise for a result object that has the format
+ * {hits: searchResult[], total: number, timedOut: boolean}
+ * where a searchResult has the format
+ * {id: string, object: domainObject, score: number}
+ *
+ * Notes:
+ * * The order of the results is not guarenteed.
+ * * A domain object qualifies as a match for a search input if
+ * the object's name property contains any of the search terms
+ * (which are generated by splitting the input at spaces).
+ * * Scores are higher for matches that have more of the terms
+ * as substrings.
+ *
+ * @param input The text input that is the query.
+ * @param timestamp The time at which this function was called.
+ * This timestamp is used as a unique identifier for this
+ * query and the corresponding results.
+ * @param maxResults (optional) The maximum number of results
+ * that this function should return.
+ * @param timeout (optional) The time after which the search should
+ * stop calculations and return partial results.
+ */
+ query: query
+
+ };
+ }
+
+
+ return GenericSearchProvider;
+ }
+);
\ No newline at end of file
diff --git a/platform/search/src/GenericSearchWorker.js b/platform/search/src/GenericSearchWorker.js
new file mode 100644
index 0000000000..69e4104602
--- /dev/null
+++ b/platform/search/src/GenericSearchWorker.js
@@ -0,0 +1,185 @@
+/*****************************************************************************
+ * 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 self*/
+
+/**
+ * Module defining GenericSearchWorker. Created by shale on 07/21/2015.
+ */
+(function () {
+ "use strict";
+
+ // An array of objects composed of domain object IDs and models
+ // {id: domainObject's ID, model: domainObject's model}
+ var indexedItems = [];
+
+ // Helper function for index()
+ // Checks whether an item with this ID is already indexed
+ function conainsItem(id) {
+ var i;
+ for (i = 0; i < indexedItems.length; i += 1) {
+ if (indexedItems[i].id === id) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Indexes an item to indexedItems.
+ *
+ * @param data An object which contains:
+ * * model: The model of the domain object
+ * * id: The ID of the domain object
+ */
+ function index(data) {
+ var message;
+
+ if (!conainsItem(data.id)) {
+ indexedItems.push({
+ id: data.id,
+ model: data.model
+ });
+ }
+ }
+
+ // Helper function for serach()
+ function convertToTerms(input) {
+ var terms = input;
+ // Shave any spaces off of the ends of the input
+ while (terms.substr(0, 1) === ' ') {
+ terms = terms.substring(1, terms.length);
+ }
+ while (terms.substr(terms.length - 1, 1) === ' ') {
+ terms = terms.substring(0, terms.length - 1);
+ }
+
+ // Then split it at spaces and asterisks
+ terms = terms.split(/ |\*/);
+
+ // Remove any empty strings from the terms
+ while (terms.indexOf('') !== -1) {
+ terms.splice(terms.indexOf(''), 1);
+ }
+
+ return terms;
+ }
+
+ // Helper function for search()
+ function scoreItem(item, input, terms) {
+ var name = item.model.name.toLocaleLowerCase(),
+ weight = 0.65,
+ score = 0.0,
+ i;
+
+ // Make the score really big if the item name and
+ // the original search input are the same
+ if (name === input) {
+ score = 42;
+ }
+
+ for (i = 0; i < terms.length; i += 1) {
+ // Increase the score if the term is in the item name
+ if (name.indexOf(terms[i]) !== -1) {
+ score += 1;
+
+ // Add extra to the score if the search term exists
+ // as its own term within the items
+ if (name.split(' ').indexOf(terms[i]) !== -1) {
+ score += 0.5;
+ }
+ }
+ }
+
+ return score * weight;
+ }
+
+ /**
+ * Gets search results from the indexedItems based on provided search
+ * input. Returns matching results from indexedItems, as well as the
+ * timestamp that was passed to it.
+ *
+ * @param data An object which contains:
+ * * input: The original string which we are searching with
+ * * maxNumber: The maximum number of search results desired
+ * * timestamp: The time identifier from when the query was made
+ */
+ function search(data) {
+ // This results dictionary will have domain object ID keys which
+ // point to the value the domain object's score.
+ var results = {},
+ input = data.input.toLocaleLowerCase(),
+ terms = convertToTerms(input),
+ message = {
+ request: 'search',
+ results: {},
+ total: 0,
+ timestamp: data.timestamp,
+ timedOut: false
+ },
+ score,
+ i,
+ id;
+
+ // If the user input is empty, we want to have no search results.
+ if (input !== '') {
+ for (i = 0; i < indexedItems.length; i += 1) {
+ // If this is taking too long, then stop
+ if (Date.now() > data.timestamp + data.timeout) {
+ message.timedOut = true;
+ break;
+ }
+
+ // Score and add items
+ score = scoreItem(indexedItems[i], input, terms);
+ if (score > 0) {
+ results[indexedItems[i].id] = score;
+ message.total += 1;
+ }
+ }
+ }
+
+ // Truncate results if there are more than maxResults
+ if (message.total > data.maxResults) {
+ i = 0;
+ for (id in results) {
+ message.results[id] = results[id];
+ i += 1;
+ if (i >= data.maxResults) {
+ break;
+ }
+ }
+ // TODO: This seems inefficient.
+ } else {
+ message.results = results;
+ }
+
+ return message;
+ }
+
+ self.onmessage = function (event) {
+ if (event.data.request === 'index') {
+ index(event.data);
+ } else if (event.data.request === 'search') {
+ self.postMessage(search(event.data));
+ }
+ };
+}());
\ No newline at end of file
diff --git a/platform/search/src/SearchAggregator.js b/platform/search/src/SearchAggregator.js
new file mode 100644
index 0000000000..da267214bf
--- /dev/null
+++ b/platform/search/src/SearchAggregator.js
@@ -0,0 +1,146 @@
+/*****************************************************************************
+ * 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*/
+
+/**
+ * Module defining SearchAggregator. Created by shale on 07/16/2015.
+ */
+define(
+ [],
+ function () {
+ "use strict";
+
+ var DEFUALT_TIMEOUT = 1000,
+ DEFAULT_MAX_RESULTS = 100;
+
+ /**
+ * Allows multiple services which provide search functionality
+ * to be treated as one.
+ *
+ * @constructor
+ * @param $q Angular's $q, for promise consolidation.
+ * @param {SearchProvider[]} providers The search providers to be
+ * aggregated.
+ */
+ function SearchAggregator($q, providers) {
+
+ // Remove duplicate objects that have the same ID. Modifies the passed
+ // array, and returns the number that were removed.
+ function filterDuplicates(results, total) {
+ var ids = {},
+ numRemoved = 0,
+ i;
+
+ for (i = 0; i < results.length; i += 1) {
+ if (ids[results[i].id]) {
+ // If this result's ID is already there, remove the object
+ results.splice(i, 1);
+ numRemoved += 1;
+
+ // Reduce loop index because we shortened the array
+ i -= 1;
+ } else {
+ // Otherwise add the ID to the list of the ones we have seen
+ ids[results[i].id] = true;
+ }
+ }
+
+ return numRemoved;
+ }
+
+ // Order the objects from highest to lowest score in the array.
+ // Modifies the passed array, as well as returns the modified array.
+ function orderByScore(results) {
+ results.sort(function (a, b) {
+ if (a.score > b.score) {
+ return -1;
+ } else if (b.score > a.score) {
+ return 1;
+ } else {
+ return 0;
+ }
+ });
+ return results;
+ }
+
+ // For documentation, see query below.
+ function queryAll(inputText, maxResults) {
+ var i,
+ timestamp = Date.now(),
+ resultPromises = [];
+
+ if (!maxResults) {
+ maxResults = DEFAULT_MAX_RESULTS;
+ }
+
+ // Send the query to all the providers
+ for (i = 0; i < providers.length; i += 1) {
+ resultPromises.push(
+ providers[i].query(inputText, timestamp, maxResults, DEFUALT_TIMEOUT)
+ );
+ }
+
+ // Get promises for results arrays
+ return $q.all(resultPromises).then(function (resultObjects) {
+ var results = [],
+ totalSum = 0,
+ i;
+
+ // Merge results
+ for (i = 0; i < resultObjects.length; i += 1) {
+ results = results.concat(resultObjects[i].hits);
+ totalSum += resultObjects[i].total;
+ }
+ // Order by score first, so that when removing repeats we keep the higher scored ones
+ orderByScore(results);
+ totalSum -= filterDuplicates(results, totalSum);
+
+ return {
+ hits: results,
+ total: totalSum,
+ timedOut: resultObjects.some(function (obj) {
+ return obj.timedOut;
+ })
+ };
+ });
+ }
+
+ return {
+ /**
+ * Sends a query to each of the providers. Returns a promise for
+ * a result object that has the format
+ * {hits: searchResult[], total: number, timedOut: boolean}
+ * where a searchResult has the format
+ * {id: string, object: domainObject, score: number}
+ *
+ * @param inputText The text input that is the query.
+ * @param maxResults (optional) The maximum number of results
+ * that this function should return. If not provided, a
+ * default of 100 will be used.
+ */
+ query: queryAll
+ };
+ }
+
+ return SearchAggregator;
+ }
+);
\ No newline at end of file
diff --git a/platform/search/test/GenericSearchProviderSpec.js b/platform/search/test/GenericSearchProviderSpec.js
new file mode 100644
index 0000000000..bec02653b8
--- /dev/null
+++ b/platform/search/test/GenericSearchProviderSpec.js
@@ -0,0 +1,157 @@
+/*****************************************************************************
+ * 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,jasmine*/
+
+/**
+ * SearchSpec. Created by shale on 07/31/2015.
+ */
+define(
+ ["../src/GenericSearchProvider"],
+ function (GenericSearchProvider) {
+ "use strict";
+
+ describe("The generic search provider ", function () {
+ var mockQ,
+ mockTimeout,
+ mockDeferred,
+ mockObjectService,
+ mockObjectPromise,
+ mockDomainObjects,
+ mockCapability,
+ mockCapabilityPromise,
+ mockWorkerService,
+ mockWorker,
+ mockRoots = ['root1', 'root2'],
+ provider,
+ mockProviderResults;
+
+ beforeEach(function () {
+ var i;
+
+ mockQ = jasmine.createSpyObj(
+ "$q",
+ [ "defer" ]
+ );
+ mockDeferred = jasmine.createSpyObj(
+ "deferred",
+ [ "resolve", "reject"]
+ );
+ mockDeferred.promise = "mock promise";
+ mockQ.defer.andReturn(mockDeferred);
+
+ mockTimeout = jasmine.createSpy("$timeout");
+
+ mockObjectService = jasmine.createSpyObj(
+ "objectService",
+ [ "getObjects" ]
+ );
+ mockObjectPromise = jasmine.createSpyObj(
+ "promise",
+ [ "then", "catch" ]
+ );
+ mockObjectService.getObjects.andReturn(mockObjectPromise);
+
+
+ mockWorkerService = jasmine.createSpyObj(
+ "workerService",
+ [ "run" ]
+ );
+ mockWorker = jasmine.createSpyObj(
+ "worker",
+ [ "postMessage" ]
+ );
+ mockWorkerService.run.andReturn(mockWorker);
+
+ mockDomainObjects = {};
+ for (i = 0; i < 4; i += 1) {
+ mockDomainObjects[i] = (
+ jasmine.createSpyObj(
+ "domainObject",
+ [ "getId", "getModel", "hasCapability", "getCapability", "useCapability" ]
+ )
+ );
+ mockDomainObjects[i].getId.andReturn(i);
+ mockDomainObjects[i].getCapability.andReturn(mockCapability);
+ }
+ // Give the first object children
+ mockDomainObjects[0].hasCapability.andReturn(true);
+ mockCapability = jasmine.createSpyObj(
+ "capability",
+ [ "invoke", "listen" ]
+ );
+ mockCapabilityPromise = jasmine.createSpyObj(
+ "promise",
+ [ "then", "catch" ]
+ );
+ mockCapability.invoke.andReturn(mockCapabilityPromise);
+ mockDomainObjects[0].getCapability.andReturn(mockCapability);
+
+ provider = new GenericSearchProvider(mockQ, mockTimeout, mockObjectService, mockWorkerService, mockRoots);
+ });
+
+ it("indexes tree on initialization", function () {
+ expect(mockObjectService.getObjects).toHaveBeenCalled();
+ expect(mockObjectPromise.then).toHaveBeenCalled();
+
+ mockObjectPromise.then.mostRecentCall.args[0](mockDomainObjects);
+
+ //mockCapabilityPromise.then.mostRecentCall.args[0](mockDomainObjects[1]);
+
+ expect(mockWorker.postMessage).toHaveBeenCalled();
+ });
+
+ it("sends search queries to the worker", function () {
+ var timestamp = Date.now();
+ provider.query(' test "query" ', timestamp, 1, 2);
+ expect(mockWorker.postMessage).toHaveBeenCalledWith({
+ request: "search",
+ input: ' test "query" ',
+ timestamp: timestamp,
+ maxNumber: 1,
+ timeout: 2
+ });
+ });
+
+ it("handles responses from the worker", function () {
+ var timestamp = Date.now(),
+ event = {
+ data: {
+ request: "search",
+ results: {
+ 1: 1,
+ 2: 2
+ },
+ total: 2,
+ timedOut: false,
+ timestamp: timestamp
+ }
+ };
+
+ provider.query(' test "query" ', timestamp);
+ mockWorker.onmessage(event);
+ mockObjectPromise.then.mostRecentCall.args[0](mockDomainObjects);
+ expect(mockDeferred.resolve).toHaveBeenCalled();
+ });
+
+ });
+ }
+);
\ No newline at end of file
diff --git a/platform/search/test/GenericSearchWorkerSpec.js b/platform/search/test/GenericSearchWorkerSpec.js
new file mode 100644
index 0000000000..2e17858400
--- /dev/null
+++ b/platform/search/test/GenericSearchWorkerSpec.js
@@ -0,0 +1,132 @@
+/*****************************************************************************
+ * 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,runs,waitsFor,beforeEach,jasmine,Worker,require*/
+
+/**
+ * SearchSpec. Created by shale on 07/31/2015.
+ */
+define(
+ [],
+ function () {
+ "use strict";
+
+ describe("The generic search worker ", function () {
+ // If this test fails, make sure this path is correct
+ var worker = new Worker(require.toUrl('platform/search/src/GenericSearchWorker.js')),
+ numObjects = 5;
+
+ beforeEach(function () {
+ var i;
+ for (i = 0; i < numObjects; i += 1) {
+ worker.postMessage(
+ {
+ request: "index",
+ id: i,
+ model: {
+ name: "object " + i,
+ id: i,
+ type: "something"
+ }
+ }
+ );
+ }
+ });
+
+ it("searches can reach all objects", function () {
+ var flag = false,
+ workerOutput,
+ resultsLength = 0;
+
+ // Search something that should return all objects
+ runs(function () {
+ worker.postMessage(
+ {
+ request: "search",
+ input: "object",
+ maxNumber: 100,
+ timestamp: Date.now(),
+ timeout: 1000
+ }
+ );
+ });
+
+ worker.onmessage = function (event) {
+ var id;
+
+ workerOutput = event.data;
+ for (id in workerOutput.results) {
+ resultsLength += 1;
+ }
+ flag = true;
+ };
+
+ waitsFor(function () {
+ return flag;
+ }, "The worker should be searching", 1000);
+
+ runs(function () {
+ expect(workerOutput).toBeDefined();
+ expect(resultsLength).toEqual(numObjects);
+ });
+ });
+
+ it("searches return only matches", function () {
+ var flag = false,
+ workerOutput,
+ resultsLength = 0;
+
+ // Search something that should return 1 object
+ runs(function () {
+ worker.postMessage(
+ {
+ request: "search",
+ input: "2",
+ maxNumber: 100,
+ timestamp: Date.now(),
+ timeout: 1000
+ }
+ );
+ });
+
+ worker.onmessage = function (event) {
+ var id;
+
+ workerOutput = event.data;
+ for (id in workerOutput.results) {
+ resultsLength += 1;
+ }
+ flag = true;
+ };
+
+ waitsFor(function () {
+ return flag;
+ }, "The worker should be searching", 1000);
+
+ runs(function () {
+ expect(workerOutput).toBeDefined();
+ expect(resultsLength).toEqual(1);
+ expect(workerOutput.results[2]).toBeDefined();
+ });
+ });
+ });
+ }
+);
\ No newline at end of file
diff --git a/platform/search/test/SearchAggregatorSpec.js b/platform/search/test/SearchAggregatorSpec.js
new file mode 100644
index 0000000000..cf35e2928e
--- /dev/null
+++ b/platform/search/test/SearchAggregatorSpec.js
@@ -0,0 +1,101 @@
+/*****************************************************************************
+ * 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,jasmine*/
+
+/**
+ * SearchSpec. Created by shale on 07/31/2015.
+ */
+define(
+ ["../src/SearchAggregator"],
+ function (SearchAggregator) {
+ "use strict";
+
+ describe("The search aggregator ", function () {
+ var mockQ,
+ mockPromise,
+ mockProviders = [],
+ aggregator,
+ mockProviderResults = [],
+ mockAggregatorResults,
+ i;
+
+ beforeEach(function () {
+ mockQ = jasmine.createSpyObj(
+ "$q",
+ [ "all" ]
+ );
+ mockPromise = jasmine.createSpyObj(
+ "promise",
+ [ "then" ]
+ );
+ for (i = 0; i < 3; i += 1) {
+ mockProviders.push(
+ jasmine.createSpyObj(
+ "mockProvider" + i,
+ [ "query" ]
+ )
+ );
+ mockProviders[i].query.andReturn(mockPromise);
+ }
+ mockQ.all.andReturn(mockPromise);
+
+ aggregator = new SearchAggregator(mockQ, mockProviders);
+ aggregator.query();
+
+ for (i = 0; i < mockProviders.length; i += 1) {
+ mockProviderResults.push({
+ hits: [
+ {
+ id: i,
+ score: 42 - i
+ },
+ {
+ id: i + 1,
+ score: 42 - (2 * i)
+ }
+ ]
+ });
+ }
+ mockAggregatorResults = mockPromise.then.mostRecentCall.args[0](mockProviderResults);
+ });
+
+ it("sends queries to all providers", function () {
+ for (i = 0; i < mockProviders.length; i += 1) {
+ expect(mockProviders[i].query).toHaveBeenCalled();
+ }
+ });
+
+ it("filters out duplicate objects", function () {
+ expect(mockAggregatorResults.hits.length).toEqual(mockProviders.length + 1);
+ expect(mockAggregatorResults.total).not.toBeLessThan(mockAggregatorResults.hits.length);
+ });
+
+ it("orders results by score", function () {
+ for (i = 1; i < mockAggregatorResults.hits.length; i += 1) {
+ expect(mockAggregatorResults.hits[i].score)
+ .not.toBeGreaterThan(mockAggregatorResults.hits[i - 1].score);
+ }
+ });
+
+ });
+ }
+);
\ No newline at end of file
diff --git a/platform/search/test/suite.json b/platform/search/test/suite.json
new file mode 100644
index 0000000000..5097bde635
--- /dev/null
+++ b/platform/search/test/suite.json
@@ -0,0 +1,5 @@
+[
+ "SearchAggregator",
+ "GenericSearchProvider",
+ "GenericSearchWorker"
+]
diff --git a/pom.xml b/pom.xml
index 8ca3cd6edb..3acfe38fa1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
gov.nasa.arc.wtd
open-mct-web
Open MCT Web
- 0.8.0-SNAPSHOT
+ 0.8.1-SNAPSHOT
war
diff --git a/protractor/README b/protractor/README
new file mode 100644
index 0000000000..5734e5702d
--- /dev/null
+++ b/protractor/README
@@ -0,0 +1,69 @@
+E2e Protractor Tests.
+
+1. Instructions:
+
+ 1. 3 Control Scripts located in bin/.
+ run.js : node script used to start tests
+ start.js: node script used to setup test(starts node,localstorage and webdriver)
+ stop.js : node script, kills the 3 process started in start.js.
+ clean.js: node script used to remove the node_module directory.(clean up directory).
+
+ 2. Use npm(Node Package Mangager) to Run Scripts.
+ a. cd protractor;
+ b. npm install;
+ c. To Run:
+ -npm start : will start processes need by protractor
+ -npm stop : will stop the processes need by protractor
+ -npm run-script run : will execute Protractor Script
+ -npm run-script all : will execute "start", "run", and "stop" script
+
+2. Directory Hierachy:
+
+ -protractor: base directory
+ -common: contains prototype javascript functions that all other tests use.
+ -Buttons: common prototype functions related to enter fullscreen
+ -CreateItem: common prototype functions related to creating an item
+ -drag: common functions to test drag and drop.
+ -editItem: common functions used to test edit functionality.
+ -Launch: common script used to navigate the specified website.
+ -RightMenu: common functions for right click menu(remove).
+ -create
+ -e2e tests that creates the specified object.
+ -delete
+ -e2e tests that removes the specified object
+ -logs
+ -ctrl.sh redirects console output of MMAP, webdriver and elastic search and pipes them to log files.
+ -UI
+ -Contains tests that test the UI(drag drop, fullscreen, info bubble)
+ -conf.js:
+ -protractor config file. Explained below
+ -stressTest:
+ Tests that are used to test for memory leaks. You can use the new tab option on WARP and then open the
+ timeline in the new tab during the browser.sleep(). Once the test is do the browser will pause and you
+ can look a the timeline results in the new tab.
+
+ NOTE: Cannot open chrome dev tools on same tab as the test are run on. Protractor uses the dev tools to
+ exectute the tests.
+
+ -StressTest will create and delete folders.
+ -StressTestBubble.js: creates manny bubbles.
+ (Delay variable in InfoGesture.js was changed to 0)
+3. Conf.js
+ Conf.js is used by protractor to setup and execute the tests.
+ -allScriptsTimeout: gives more time for protractor to synchronize with the page.
+ -jasmineNodeOpts: Protractor uses jasmine for the tests and jasmine has a default time out 30 seconds
+ per "it" test. Changed to maximume allowed time 360000 ms
+ -seleniumAddress: Protractor uses a Selenium server as a "proxy" between the test scripts and the browser
+ driver. A stand a lone version comes with protractor and to run use "webdriver-manager"
+ default address is: http://localhost:4444/wd/hub.
+ -specs[]: Is an array of files. Each File should have a "describe, it" test to be executed by protractor.
+ -capabilities: Tells protractor what browser to use and any browser arguments.
+
+4. bundle.json
+ bundle.json is used by npm to determine dependencies and location of script files.
+ -Dependencies:
+ "protractor": Contains protractor and webdriver package.
+ "psnode": Window/Unix Command, used for list/kill process.(ps aux)
+ "shelljs": Window/Unix Common JS Commands. eg rm,ls,exec
+ "sleep": Window/Unix Commands used to sleep the script
+ "string": Window/Unix Commands for string manipulation.
\ No newline at end of file
diff --git a/protractor/UI/Fullscreen.js b/protractor/UI/Fullscreen.js
index 3c1c785228..532ad318d8 100644
--- a/protractor/UI/Fullscreen.js
+++ b/protractor/UI/Fullscreen.js
@@ -22,7 +22,7 @@
//TODO Add filter for duplications/
var fullScreenFile = require("../common/Buttons");
-describe('Test Fullscreen', function() {
+describe('Enable Fullscreen', function() {
var fullScreenClass = new fullScreenFile();
beforeEach(require('../common/Launch'));
diff --git a/protractor/UI/InfoBubble.js b/protractor/UI/InfoBubble.js
index 274b7966b0..c88e9018d0 100644
--- a/protractor/UI/InfoBubble.js
+++ b/protractor/UI/InfoBubble.js
@@ -25,7 +25,7 @@ var itemEdit = require("../common/EditItem");
var rightMenu = require("../common/RightMenu");
var Drag = require("../common/drag");
-describe('Test Info Bubble', function() {
+describe('Info Bubble', function() {
var fullScreenClass = new fullScreenFile();
var createClass = new createItem();
var editItemClass = new itemEdit();
diff --git a/protractor/UI/NewWindow.js b/protractor/UI/NewWindow.js
index 7a714d79a2..1e98bbc8b4 100644
--- a/protractor/UI/NewWindow.js
+++ b/protractor/UI/NewWindow.js
@@ -24,7 +24,7 @@ var createClassFile = require("../common/CreateItem")
var itemEdit = require("../common/EditItem");
var rightMenu = require("../common/RightMenu.js");
-describe('Test New Window', function() {
+describe('New Window', function() {
var fullScreenClass = new fullScreenFile();
var createClass = new createClassFile();
var editItemClass = new itemEdit();
diff --git a/protractor/UI/RightClick.js b/protractor/UI/RightClick.js
index 0ae4dd0708..5f7d389313 100644
--- a/protractor/UI/RightClick.js
+++ b/protractor/UI/RightClick.js
@@ -21,28 +21,64 @@
*****************************************************************************/
var right_click = require("../common/RightMenu.js");
var Create = require("../common/CreateItem")
-describe('Right Click Interations', function() {
+var itemEdit = require("../common/EditItem");
+
+describe('The Right Menu', function() {
var clickClass = new right_click();
var createClass = new Create();
+ var editItemClass = new itemEdit();
var ITEM_NAME = "Folder";
var ITEM_TYPE = "folder";
var ITEM_MENU_GLYPH = 'F\nFolder';
+ var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items';
beforeEach(require('../common/Launch'));
- it('should delete the specified object', function(){
- createClass.createButton().click();
- var folder = createClass.selectNewItem(ITEM_TYPE);
- expect(folder.getText()).toEqual([ ITEM_MENU_GLYPH ]);
- browser.sleep(1000);
- folder.click()
- browser.sleep(1000);
- browser.wait(function () {
- return element.all(by.model('ngModel[field]')).isDisplayed();
+ it('should Dissapear After Delete', function(){
+ browser.wait(function() {
+ createClass.createButton().click();
+ return true;
+ }).then(function (){
+ var folder = createClass.selectNewItem(ITEM_TYPE);
+ expect(folder.getText()).toEqual([ ITEM_MENU_GLYPH ]);
+ browser.sleep(1000);
+ folder.click()
+ }).then(function() {
+ browser.wait(function () {
+ return element.all(by.model('ngModel[field]')).isDisplayed();
+ })
+ createClass.fillFolderForum(ITEM_NAME, ITEM_TYPE).click();
+ browser.sleep(1000);
+ }).then(function (){
+ var item = editItemClass.SelectItem(ITEM_GRID_SELECT);
+ expect(item.count()).toBe(1);
+ browser.sleep(1000);
+ }).then(function () {
+ var MyItem = ">\nF\nMy Items"
+ element.all(by.repeater('child in composition')).filter(function (ele){
+ return ele.getText().then(function(text) {
+ return text === MyItem;
+ });
+ }).all(by.css('.ui-symbol.view-control.ng-binding.ng-scope')).click();
+ var object = element.all(by.repeater('child in composition')).filter(function (ele){
+ return ele.getText().then(function(text) {
+ return text === ">\nF\nFolder";
+ });
+ });
+ browser.sleep(1000)
+ browser.actions().mouseMove(object.get(0)).perform();
+ browser.actions().click(protractor.Button.RIGHT).perform();
+ browser.sleep(1000)
+ var menu = element.all(by.css('.ng-binding')).filter(function (ele){
+ return ele.getText().then(function (text) {
+ return text == "Z\nRemove";
+ })
+ })
+ menu.click();
+ browser.sleep(1000)
+
+ expect(menu.isDisplayed()).toBe(false);
})
- createClass.fillFolderForum(ITEM_NAME, ITEM_TYPE).click();
- clickClass.delete(ITEM_NAME);
- browser.sleep(1000);
});
});
diff --git a/protractor/bin/clean.js b/protractor/bin/clean.js
new file mode 100755
index 0000000000..82e776901f
--- /dev/null
+++ b/protractor/bin/clean.js
@@ -0,0 +1,15 @@
+#! /usr/bin/env node
+var shell = require("shelljs/global");
+
+var startdir = process.cwd();
+var command = "npm unlink";
+
+console.log("Cleaning Directory")
+exec(command, function(code, output) {
+ if(code != 0){
+ console.log('Exit code:', code);
+ console.log('Program output:', output);
+ }
+});
+console.log("rm -rf node_modules")
+rm('-rf', __dirname + "/../node_modules")
diff --git a/protractor/bin/ctrl.sh b/protractor/bin/ctrl.sh
new file mode 100755
index 0000000000..faf385d2ad
--- /dev/null
+++ b/protractor/bin/ctrl.sh
@@ -0,0 +1,90 @@
+#! /bin/bash
+ARGUMENT=$1;
+
+if [ $# != 1 ]; then
+ echo "Expected 1 Aurgument. Received " $# 1>&2;
+ exit 1
+fi
+#Start webdrive and http-server
+if [ $ARGUMENT == start ]; then
+ echo "Creating Log Directory ..."
+ mkdir logs;
+
+ cd ..
+ node app.js -p 1984 -x platform/persistence/elastic -i example/persistence > protractor/logs/nodeApp.log 2>&1 &
+ sleep 3;
+ if grep -iq "Error" protractor/logs/nodeApp.log; then
+ if grep -iq "minimist" protractor/logs/nodeApp.log; then
+ echo " Node Failed Because Minimist is not installed"
+ echo " Installng Minimist ..."
+ npm install minimist express > protractor/logs/minimist.log 2>&1 &
+ wait $!
+ if [ $? != 0 ]; then
+ echo " Error: minimist"
+ echo " Check Log file"
+ echo
+ else
+ echo " Started: Minimist"
+ echo
+ node app.js -p 1984 -x platform/persistence/elastic -i example/persistence > protractor/logs/nodeApp.log 2>&1 &
+ if grep -iq "Error" protractor/logs/nodeApp.log; then
+ echo " Error: node app failed"
+ echo " Check Log file"
+ echo
+ else
+ echo " Started: node app.js"
+ echo
+ fi
+ fi
+ else
+ echo " Error: node app failed"
+ echo " Check Log file"
+ echo
+ fi
+ else
+ echo " Started: node app.js"
+ echo
+ fi
+ echo "Starting webdriver ..."
+
+ cd protractor;
+ webdriver-manager start > logs/webdriver.log 2>&1 &
+ sleep 3;
+ if grep -iq "Exception" logs/webdriver.log; then
+ echo " Error: webdriver-manager"
+ echo " Check Log file"
+ echo
+ else
+ echo " Started: webdriver-manager"
+ fi
+ echo "Starting Elastic Search..."
+
+ elasticsearch > logs/elasticSearch.log 2>&1 &
+ sleep 3;
+ if grep -iq "Exception" logs/elasticSearch.log; then
+ echo " Error: ElasticSearch"
+ echo " Check Log file"
+ echo
+ else
+ echo " Started: ElasticSearch"
+ fi
+#Runs Protractor tests
+elif [ $ARGUMENT == run ]; then
+ protractor ./conf.js
+#Kill Process
+elif [ $ARGUMENT == stop ]; then
+ echo "Removing logs"
+ rm -rf logs
+ echo "Stopping Node"
+ kill $(ps aux | grep "[n]ode app.js"| awk '{print $2}');
+
+ echo "Stopping webdriver ..."
+ kill $(ps aux | grep "[p]rotractor" | awk '{print $2}');
+ kill $(ps aux | grep "[w]ebdriver-manager" | awk '{print $2}');
+ sleep 1;
+ echo "Stopping Elastic..."
+ kill $(ps aux | grep "[e]lastic" | awk '{print $2}');
+ sleep 1;
+else
+ echo "Unkown: Command" $1;
+fi
diff --git a/protractor/bin/run.js b/protractor/bin/run.js
new file mode 100755
index 0000000000..316caa11d0
--- /dev/null
+++ b/protractor/bin/run.js
@@ -0,0 +1,12 @@
+#! /usr/bin/env node
+var shell = require("shelljs/global");
+var sleep = require('sleep');
+
+var command = __dirname + "/../node_modules/protractor/bin/protractor " +__dirname + "/../conf.js";
+console.log("Executing Protractor Test")
+exec(command, function(code, output) {
+ if(code != 0){
+ console.log('Exit code:', code);
+ console.log('Program output:', output);
+ }
+});
\ No newline at end of file
diff --git a/protractor/bin/start.js b/protractor/bin/start.js
new file mode 100755
index 0000000000..21aacc7efe
--- /dev/null
+++ b/protractor/bin/start.js
@@ -0,0 +1,40 @@
+#! /usr/bin/env node
+var shell,sleep;
+try {
+ shell = require("shelljs/global");
+ sleep = require('sleep');
+}catch (e){
+ console.log("Dependencies Error");
+ console.log("Run npm install");
+ throw (e);
+}
+///Users/jsanderf/git/elastic/wtd/protractor/bin
+var startdir = process.cwd();
+var command;
+mkdir(__dirname + '/../logs');
+
+command = __dirname + "/../node_modules/protractor/bin/webdriver-manager update";
+console.log("Installing Webdriver");
+exec(command,{async:false});
+sleep.sleep(1);
+
+console.log();
+cd(__dirname + '/../../');
+console.log('Installing Dependencies');
+exec("npm install minimist express", {async:false});
+console.log('Starting Node');
+sleep.sleep(1);
+exec("node app.js -p 1984 -x example/persistence -x platform/persistence/elastic -i example/localstorage > protractor/logs/nodeApp.log 2>&1 &", {async:false});
+console.log(' Started Node');
+
+console.log();
+console.log('Starting Webdriver');
+sleep.sleep(1);
+exec("protractor/node_modules/protractor/bin/webdriver-manager start --standalone> protractor/logs/webdriver.log 2>&1 &",{async:false});
+if(error() == null){
+ console.log(" Webdriver Started");
+}else{
+ console.log(" Error : ", error());
+}
+sleep.sleep(1);
+cd(startdir);
diff --git a/protractor/bin/stop.js b/protractor/bin/stop.js
new file mode 100755
index 0000000000..ac2c3b4295
--- /dev/null
+++ b/protractor/bin/stop.js
@@ -0,0 +1,44 @@
+#! /usr/bin/env node
+
+var shell = require("shelljs/global");
+var ps = require('psnode');
+var S = require('string');
+var sleep = require('sleep');
+
+// A simple pid lookup
+ps.list(function(err, results) {
+
+ results.forEach(function( process ){
+ //Killing Node
+ if(S(process.command).contains("node app.js")) {
+ console.log();
+ console.log( 'Killing Node: %s', process.command);
+ ps.kill(process.pid, function(err, stdout) {
+ if (err) {
+ throw new Error(err);
+ }
+ console.log(stdout);
+ });
+ }else if(S(process.command).contains("webdriver")) {
+ console.log();
+ console.log( 'Killing WebDriver: %s', process.command);
+ ps.kill(process.pid, function(err, stdout) {
+ if (err){
+ throw new Error(err);
+ }
+ console.log(stdout);
+ });
+ }else if(S(process.command).contains("protractor")) {
+ console.log();
+ console.log( 'Killing Chrome Drive: %s', process.command);
+ ps.kill(process.pid, function(err, stdout) {
+ if (err){
+ throw new Error(err);
+ }
+ console.log(stdout);
+ });
+ }
+ });
+});
+
+
diff --git a/protractor/common/Launch.js b/protractor/common/Launch.js
index 2b700672cc..fd745f94c3 100644
--- a/protractor/common/Launch.js
+++ b/protractor/common/Launch.js
@@ -24,6 +24,6 @@
module.exports = function launch() {
'use strict';
browser.ignoreSynchronization = true;
- browser.get('http://localhost:1984/');
- browser.sleep(2000); // 20 seconds
+ browser.get('http://localhost:1984');
+ browser.sleep(2000); // 2 seconds
};
diff --git a/protractor/common/RightMenu.js b/protractor/common/RightMenu.js
index 490d876d87..d1375d0533 100644
--- a/protractor/common/RightMenu.js
+++ b/protractor/common/RightMenu.js
@@ -24,18 +24,25 @@ var RightMenu = (function () {
function RightMenu() {
}
+ function carrotMyItem(){
+ var MyItem = ">\nF\nMy Items"
+ element.all(by.repeater('child in composition')).filter(function (ele){
+ return ele.getText().then(function(text) {
+ return text === MyItem;
+ });
+ }).all(by.css('.ui-symbol.view-control.ng-binding.ng-scope')).click();
+ }
//RightMenu Click on Object
RightMenu.prototype.delete = function (name, flag) {
if(typeof flag === 'undefined'){
flag = true;
}
if(flag === true){
- var carrot = element.all(by.css('.ui-symbol.view-control.ng-binding.ng-scope')).get(0).click();
+ carrotMyItem();
}
browser.sleep(1000)
var object = element.all(by.repeater('child in composition')).filter(function (ele){
return ele.getText().then(function(text) {
- //expect(text).toEqual("3");
return text === name;
});
});
@@ -43,7 +50,7 @@ var RightMenu = (function () {
browser.actions().mouseMove(object.get(0)).perform();
browser.actions().click(protractor.Button.RIGHT).perform();
browser.sleep(1000)
- var remove = element.all(by.css('.ng-binding')).filter(function (ele){
+ element.all(by.css('.ng-binding')).filter(function (ele){
return ele.getText().then(function (text) {
return text == "Z\nRemove";
})
@@ -58,11 +65,10 @@ var RightMenu = (function () {
});
};
RightMenu.prototype.reset = function (name) {
- var carrot = element.all(by.css('.ui-symbol.view-control.ng-binding.ng-scope')).click();
+ carrotMyItem();
browser.sleep(1000)
var object = element.all(by.repeater('child in composition')).filter(function (ele){
return ele.getText().then(function(text) {
- //expect(text).toEqual("3");
return text === name;
});
}).click();
@@ -75,19 +81,19 @@ var RightMenu = (function () {
return text == "r\nRestart at 0";
})
}).click();
+ browser.sleep(1000)
};
+ //click '<', true==yes false==no
RightMenu.prototype.select = function(name, flag){
if(typeof flag == "undefined"){
flag = true;
}
- //click '<', true==yes false==no
if(flag == true){
- var carrot = element.all(by.css('.ui-symbol.view-control.ng-binding.ng-scope')).click();
+ carrotMyItem();
}
browser.sleep(1000)
return element.all(by.repeater('child in composition')).filter(function (ele){
return ele.getText().then(function(text) {
- // expect(text).toEqual("3");
return text === name;
});
});
@@ -96,7 +102,6 @@ var RightMenu = (function () {
RightMenu.prototype.dragDrop = function(name){
var object = element.all(by.repeater('child in composition')).filter(function (ele){
return ele.getText().then(function(text) {
- //expect(text).toEqual("3");
return text === name;
});
});
diff --git a/protractor/conf.js b/protractor/conf.js
index c33e196157..8b828fcbd7 100644
--- a/protractor/conf.js
+++ b/protractor/conf.js
@@ -24,34 +24,34 @@
// conf.js
exports.config = {
allScriptsTimeout: 500000,
- defaultTimeoutInterval: 60000,
+ jasmineNodeOpts: {defaultTimeoutInterval: 360000},
seleniumAddress: 'http://localhost:4444/wd/hub',
- //specs: ['StressTest.js'],
+ //specs: ['StressTestCarrot.js'],
specs: [
- //'create/CreateActivity.js',
- //'delete/DeleteActivity.js',
- //'create/CreateActivityMode.js',
- //'delete/DeleteActivityMode.js',
- //'create/CreateActivityMode.js',
- //'create/CreateClock.js',
- //'delete/DeleteClock.js',
+ // 'create/CreateActivity.js',
+ // 'delete/DeleteActivity.js',
+ // 'create/CreateActivityMode.js',
+ // 'delete/DeleteActivityMode.js',
+ // 'create/CreateClock.js',
+ // 'delete/DeleteClock.js',
'create/CreateDisplay.js',
- //'delete/DeleteDisplay.js',
+ 'delete/DeleteDisplay.js',
'create/CreateFolder.js',
- //'delete/DeleteFolder.js',
- 'create/CreateTelemetry.js',
- //'delete/DeleteTelemetry.js',
- //'create/CreateTimeline.js',
- //'delete/DeleteTimeline.js',
- //'create/CreateTimer.js',
- //'delete/DeleteTimer.js',
+ 'delete/DeleteFolder.js',
+ // 'create/CreateTelemetry.js',
+ // 'delete/DeleteTelemetry.js',
+ // 'create/CreateTimeline.js',
+ // 'delete/DeleteTimeline.js',
+ // 'create/CreateTimer.js',
+ // 'delete/DeleteTimer.js',
'create/CreateWebPage.js',
- //'delete/DeleteWebPage.js',
+ 'delete/DeleteWebPage.js',
'UI/Fullscreen.js',
'create/CreateButton.js',
//"UI/DragDrop.js",
- //"UI/NewWindow.js",
- 'UI/InfoBubble.js'
+ "UI/NewWindow.js"
+ //'UI/InfoBubble.js',
+ //'UI/RightClick.js'
],
capabilities: {
'browserName': 'chrome', // or 'safari'
@@ -61,7 +61,7 @@ exports.config = {
// Allow specifying binary location as an environment variable,
// for cases where Chrome is not installed in a usual location.
-if (process.env.PROTRACTOR_CHROME_BINARY) {
+if (process.env.CHROME_BIN) {
exports.config.capabilities.chromeOptions.binary =
- process.env.PROTRACTOR_CHROME_BINARY;
+ process.env.CHROME_BIN;
}
diff --git a/protractor/create/CreateActivityMode.js b/protractor/create/CreateActivityMode.js
index e9469749aa..17ed700ae6 100644
--- a/protractor/create/CreateActivityMode.js
+++ b/protractor/create/CreateActivityMode.js
@@ -22,7 +22,7 @@
var itemCreate = require("../common/CreateItem");
var itemEdit = require("../common/EditItem");
-describe('Create Web Page', function() {
+describe('Create Activity Mode', function() {
var createClass = new itemCreate();
var editItemClass = new itemEdit();
var ITEM_NAME = "Activity Mode";
diff --git a/protractor/create/CreateClock.js b/protractor/create/CreateClock.js
index d1dc781b58..940db62af4 100644
--- a/protractor/create/CreateClock.js
+++ b/protractor/create/CreateClock.js
@@ -57,7 +57,7 @@ describe('Create Clock', function() {
});
it('should check clock', function () {
- function getTime() {
+ function getTime(flag) {
function addZero(time){
if(time < 10){
return '0' + time;
@@ -66,7 +66,6 @@ describe('Create Clock', function() {
}
var currentdate = new Date();
-
var month = currentdate.getMonth() + 1;
month = addZero(month);
@@ -77,6 +76,9 @@ describe('Create Clock', function() {
hour = addZero(hour);
var second = currentdate.getSeconds();
+ if(flag == true) {
+ second = second + 1;
+ }
second = addZero(second);
var minute = currentdate.getMinutes();
@@ -85,17 +87,23 @@ describe('Create Clock', function() {
return ("UTC " + currentdate.getFullYear() + "/" + (month) + "/" +
day + " " + (hour) + ":" + minute + ":" + second + " PM");
}
-
- var current,clock;
- rightClickClass.select(ITEM_MENU_GLYPH, true).click().then(function () {
- browser.sleep(1000);
- current = browser.executeScript(getTime);
- }).then(function () {
- clock = element(by.css('.l-time-display.l-digital.l-clock.s-clock.ng-scope'));
- clock.getText().then(function (time) {
- expect(current).toEqual(time);
- })
+ this.addMatchers({
+ toBeIn: function(expected){
+ var posibilities = Array.isArray(this.actual) ? this.actual : [this.actual];
+ return posibilities.indexOf(expected) > -1;
+ }
})
-
+ rightClickClass.select(ITEM_MENU_GLYPH, true).click().then(function () {
+ browser.sleep(1000);
+ browser.executeScript(getTime, false).then(function(current){
+ browser.executeScript(getTime, true).then(function(current1) {
+ var clock = element(by.css('.l-time-display.l-digital.l-clock.s-clock.ng-scope'));
+ clock.getText().then(function (ele) {
+ expect([current,current1]).toBeIn(ele);
+ })
+ });
+ });
+
+ })
});
});
diff --git a/protractor/create/CreateTimer.js b/protractor/create/CreateTimer.js
index d8059c1f59..e83fedfedf 100644
--- a/protractor/create/CreateTimer.js
+++ b/protractor/create/CreateTimer.js
@@ -63,7 +63,11 @@ describe('Create Timer', function() {
browser.sleep(1000)
var timer = element(by.css('.value.ng-binding.active'))
timer.getText().then(function (time) {
- expect(time).toEqual("0D 00:00:01")
+ var timerChecker = false;
+ if(time == "0D 00:00:01" || time == "0D 00:00:02"){
+ timerChecker = true;
+ }
+ expect(timerChecker).toEqual(true)
})
});
diff --git a/protractor/package.json b/protractor/package.json
new file mode 100644
index 0000000000..b43b9b1cdb
--- /dev/null
+++ b/protractor/package.json
@@ -0,0 +1,20 @@
+{
+ "name": "ProtractorLauncher",
+ "version": "1.0.0",
+ "scripts" : {
+ "start" : "bin/start.js",
+ "protractor" : "bin/run.js",
+ "stop" : "bin/stop.js",
+ "all" : "bin/start.js; bin/run.js; bin/stop.js;",
+ "clean" : "bin/clean.js"
+ },
+ "dependencies": {
+ "protractor": "^2.1.0",
+ "psnode": "0.0.1",
+ "shelljs": "^0.5.2",
+ "sleep": "^3.0.0",
+ "string": "^3.3.1"
+ },
+ "description": "E2e Protractor Tests.",
+ "license": "ISC"
+}
diff --git a/protractor/StressTest.js b/protractor/stressTest/StressTest.js
similarity index 74%
rename from protractor/StressTest.js
rename to protractor/stressTest/StressTest.js
index 5e4a8b1507..108e431868 100644
--- a/protractor/StressTest.js
+++ b/protractor/stressTest/StressTest.js
@@ -19,10 +19,9 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
-//TODO Add filter for duplications/
-var itemCreate = require("./common/CreateItem");
-var itemEdit = require("./common/EditItem");
-var right_click = require("./common/RightMenu.js");
+var itemCreate = require("../common/CreateItem");
+var itemEdit = require("../common/EditItem");
+var right_click = require("../common/RightMenu.js");
describe('Create Folder', function() {
var clickClass = new right_click();
@@ -41,31 +40,35 @@ describe('Create Folder', function() {
});
it('should Create new Folder', function(){
browser.sleep(5000);
- for(var i=0; i < 50; i++){
+ for(var i=0; i < 25; i++){
browser.wait(function() {
createClass.createButton().click();
return true;
}).then(function (){
var folder = createClass.selectNewItem(ITEM_TYPE);
expect(folder.getText()).toEqual([ ITEM_MENU_GLYPH ]);
- browser.sleep(1000);
+ browser.sleep(500);
folder.click()
}).then(function() {
browser.wait(function () {
return element.all(by.model('ngModel[field]')).isDisplayed();
})
createClass.fillFolderForum(ITEM_NAME, ITEM_TYPE).click();
- browser.sleep(1000);
+ browser.sleep(500);
}).then(function (){
- browser.sleep(1000);
- // if(i === 1){
- clickClass.delete(ITEM_SIDE_SELECT, true);
- element.all(by.css('.ui-symbol.view-control.ng-binding.ng-scope')).click();
- // }else{
- browser.sleep(1000);
-
+ browser.sleep(500);
+ clickClass.delete(ITEM_SIDE_SELECT, true);
+ //element.all(by.css('.ui-symbol.view-control.ng-binding.ng-scope')).click();
+
+
+ var MyItem = ">\nF\nMy Items"
+ element.all(by.repeater('child in composition')).filter(function (ele){
+ return ele.getText().then(function(text) {
+ //expect(text).toEqual(MyItem);
+ return text === MyItem;
+ });
+ }).all(by.css('.ui-symbol.view-control.ng-binding.ng-scope')).click();
// clickClass.delete(ITEM_SIDE_SELECT, false);
- // }
});
}
browser.pause();
diff --git a/protractor/stressTest/StressTestBubble.js b/protractor/stressTest/StressTestBubble.js
new file mode 100644
index 0000000000..b06b29c1b9
--- /dev/null
+++ b/protractor/stressTest/StressTestBubble.js
@@ -0,0 +1,59 @@
+/*****************************************************************************
+ * 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.
+ *****************************************************************************/StressTestBubble.jsStressTestBubble.js
+var itemCreate = require("../common/CreateItem");
+var itemEdit = require("../common/EditItem");
+var right_click = require("../common/RightMenu.js");
+
+describe('Create Folder', function() {
+ var clickClass = new right_click();
+ var createClass = new itemCreate();
+ var editItemClass = new itemEdit();
+ var ITEM_NAME = "Folder";
+ var ITEM_TYPE = "folder";
+ var ITEM_MENU_GLYPH = 'F\nFolder';
+ var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items';
+ var ITEM_SIDE_SELECT = ">\nF\nFolder"
+
+ beforeEach(function() {
+ browser.ignoreSynchronization = true;
+ browser.get('http://localhost:1984/warp/');
+ browser.sleep(2000); // 20 seconds
+ });
+ it('should Create new Folder', function(){
+ browser.sleep(10000);
+ for(var i=0; i < 1000; i++){
+ var object = element.all(by.repeater('child in composition')).filter(function (ele){
+ return ele.getText().then(function(text) {
+ return text === ">\nF\nMy Items";
+ });
+ });
+ //browser.sleep(1000)
+ browser.actions().mouseMove(object.get(0)).perform();
+ //browser.actions().click(protractor.Button.RIGHT).perform();
+
+ element.all(by.css('.items-holder.grid.abs.ng-scope')).click();
+ }
+ browser.pause();
+
+ });
+
+});
diff --git a/protractor/stressTest/StressTestCreateButton.js b/protractor/stressTest/StressTestCreateButton.js
new file mode 100644
index 0000000000..25debf3bba
--- /dev/null
+++ b/protractor/stressTest/StressTestCreateButton.js
@@ -0,0 +1,56 @@
+/*****************************************************************************
+ * 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.
+ *****************************************************************************/
+var itemCreate = require("../common/CreateItem");
+var itemEdit = require("../common/EditItem");
+var right_click = require("../common/RightMenu.js");
+
+describe('Create Folder', function() {
+ var clickClass = new right_click();
+ var createClass = new itemCreate();
+ var editItemClass = new itemEdit();
+ var ITEM_NAME = "Folder";
+ var ITEM_TYPE = "folder";
+ var ITEM_MENU_GLYPH = 'F\nFolder';
+ var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items';
+ var ITEM_SIDE_SELECT = ">\nF\nFolder"
+
+ beforeEach(function() {
+ browser.ignoreSynchronization = true;
+ browser.get('http://localhost:1984/warp/');
+ browser.sleep(2000); // 20 seconds
+ });
+ it('should Create new Folder', function(){
+ browser.sleep(10000);
+ for(var i=0; i < 1000; i++){
+ createClass.createButton().click();
+
+ //browser.sleep(1000)
+ //browser.actions().mouseMove(object.get(0)).perform();
+ //browser.actions().click(protractor.Button.RIGHT).perform();
+
+ element.all(by.css('.items-holder.grid.abs.ng-scope')).click();
+ }
+ browser.pause();
+
+ });
+
+});
diff --git a/protractor/stressTest/StressTestMenu.js b/protractor/stressTest/StressTestMenu.js
new file mode 100644
index 0000000000..d6e30bc5b2
--- /dev/null
+++ b/protractor/stressTest/StressTestMenu.js
@@ -0,0 +1,55 @@
+/*****************************************************************************
+ * 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.
+ *****************************************************************************/
+var itemCreate = require("../common/CreateItem");
+var itemEdit = require("../common/EditItem");
+var right_click = require("../common/RightMenu.js");
+
+describe('Create Folder', function() {
+ var clickClass = new right_click();
+ var createClass = new itemCreate();
+ var editItemClass = new itemEdit();
+ var ITEM_NAME = "Folder";
+ var ITEM_TYPE = "folder";
+ var ITEM_MENU_GLYPH = 'F\nFolder';
+ var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items';
+ var ITEM_SIDE_SELECT = ">\nF\nFolder"
+
+ beforeEach(function() {
+ browser.ignoreSynchronization = true;
+ browser.get('http://localhost:1984/warp/');
+ browser.sleep(2000); // 20 seconds
+ });
+ it('should Create new Folder', function(){
+ browser.sleep(10000);
+ for(var i=0; i < 1000; i++){
+ browser.wait(function() {
+ createClass.createButton().click();
+ return true;
+ }).then(function (){
+ element.all(by.css('.items-holder.grid.abs.ng-scope')).click();
+ })
+ }
+ browser.pause();
+
+ });
+
+});
diff --git a/protractor/stressTest/StressTestNewPage.js b/protractor/stressTest/StressTestNewPage.js
new file mode 100644
index 0000000000..2b0e82fbb1
--- /dev/null
+++ b/protractor/stressTest/StressTestNewPage.js
@@ -0,0 +1,61 @@
+/*****************************************************************************
+ * 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.
+ *****************************************************************************/
+var itemCreate = require("../common/CreateItem");
+var itemEdit = require("../common/EditItem");
+var right_click = require("../common/RightMenu.js");
+var fullScreenFile = require("../common/FullScreen");
+
+describe('Create Folder', function() {
+ var clickClass = new right_click();
+ var createClass = new itemCreate();
+ var editItemClass = new itemEdit();
+ var fullScreenClass = new fullScreenFile();
+
+ var ITEM_NAME = "Folder";
+ var ITEM_TYPE = "folder";
+ var ITEM_MENU_GLYPH = 'F\nFolder';
+ var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items';
+ var ITEM_SIDE_SELECT = ">\nF\nFolder"
+
+ beforeEach(function() {
+ browser.ignoreSynchronization = true;
+ browser.get('http://localhost:1984/warp/');
+ browser.sleep(2000); // 20 seconds
+ });
+ it('should Create new Folder', function(){
+ browser.sleep(15000);
+ for(var i=0; i < 1000; i++){
+ fullScreenClass.newWidnow().click();
+
+ browser.getAllWindowHandles().then(function (handles) {
+ //browser.driver.switchTo().window(handles[1]);
+ browser.sleep(1000);
+ browser.driver.close();
+ browser.sleep(1000);
+ // browser.driver.switchTo().window(handles[0]);
+ });
+ }
+ browser.pause();
+
+ });
+
+});
diff --git a/protractor/stressTest/StressTestRightClick.js b/protractor/stressTest/StressTestRightClick.js
new file mode 100644
index 0000000000..f16f876a90
--- /dev/null
+++ b/protractor/stressTest/StressTestRightClick.js
@@ -0,0 +1,59 @@
+/*****************************************************************************
+ * 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.
+ *****************************************************************************/
+var itemCreate = require("../common/CreateItem");
+var itemEdit = require("../common/EditItem");
+var right_click = require("../common/RightMenu.js");
+
+describe('Create Folder', function() {
+ var clickClass = new right_click();
+ var createClass = new itemCreate();
+ var editItemClass = new itemEdit();
+ var ITEM_NAME = "Folder";
+ var ITEM_TYPE = "folder";
+ var ITEM_MENU_GLYPH = 'F\nFolder';
+ var ITEM_GRID_SELECT = 'P\nF\nFolder\n0 Items';
+ var ITEM_SIDE_SELECT = ">\nF\nFolder"
+
+ beforeEach(function() {
+ browser.ignoreSynchronization = true;
+ browser.get('http://localhost:1984/warp/');
+ browser.sleep(2000); // 20 seconds
+ });
+ it('should Create new Folder', function(){
+ browser.sleep(8000);
+ for(var i=0; i < 1000; i++){
+ var object = element.all(by.repeater('child in composition')).filter(function (ele){
+ return ele.getText().then(function(text) {
+ return text === ">\nF\nMy Items";
+ });
+ });
+ //browser.sleep(1000)
+ browser.actions().mouseMove(object.get(0)).perform();
+ browser.actions().click(protractor.Button.RIGHT).perform();
+
+ element.all(by.css('.items-holder.grid.abs.ng-scope')).click();
+ }
+ browser.pause();
+
+ });
+
+});