diff --git a/copyright-notice.html b/copyright-notice.html
index 2e323d1e392..ffcbb9a4e18 100644
--- a/copyright-notice.html
+++ b/copyright-notice.html
@@ -1,5 +1,5 @@
\ No newline at end of file
+-->
diff --git a/copyright-notice.js b/copyright-notice.js
index 82fd0deeb42..dc566ef7eb9 100644
--- a/copyright-notice.js
+++ b/copyright-notice.js
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Open MCT, Copyright (c) 2014-2018, United States Government
+ * Open MCT, Copyright (c) 2014-2020, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
@@ -18,4 +18,4 @@
* 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.
- *****************************************************************************/
\ No newline at end of file
+ *****************************************************************************/
diff --git a/example/generator/GeneratorMetadataProvider.js b/example/generator/GeneratorMetadataProvider.js
index ae62f748620..f9618abc156 100644
--- a/example/generator/GeneratorMetadataProvider.js
+++ b/example/generator/GeneratorMetadataProvider.js
@@ -9,7 +9,8 @@ define([
values: [
{
key: "name",
- name: "Name"
+ name: "Name",
+ format: "string"
},
{
key: "utc",
diff --git a/package.json b/package.json
index 50a8d53cd93..bd876eb67eb 100644
--- a/package.json
+++ b/package.json
@@ -64,6 +64,7 @@
"request": "^2.69.0",
"split": "^1.0.0",
"style-loader": "^1.0.1",
+ "uuid": "^3.3.3",
"v8-compile-cache": "^1.1.0",
"vue": "2.5.6",
"vue-loader": "^15.2.6",
diff --git a/src/MCT.js b/src/MCT.js
index c07dd398403..f7eb9db14d5 100644
--- a/src/MCT.js
+++ b/src/MCT.js
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Open MCT, Copyright (c) 2014-2018, United States Government
+ * Open MCT, Copyright (c) 2014-2020, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
@@ -264,6 +264,8 @@ define([
this.install(this.plugins.GoToOriginalAction());
this.install(this.plugins.ImportExport());
this.install(this.plugins.WebPage());
+ this.install(this.plugins.Condition());
+ this.install(this.plugins.ConditionWidget());
}
MCT.prototype = Object.create(EventEmitter.prototype);
diff --git a/src/plugins/LADTable/components/LADTable.vue b/src/plugins/LADTable/components/LADTable.vue
index 4405a7d49c4..f304603a7b2 100644
--- a/src/plugins/LADTable/components/LADTable.vue
+++ b/src/plugins/LADTable/components/LADTable.vue
@@ -21,22 +21,24 @@
*****************************************************************************/
-
-
-
-
Name
-
Timestamp
-
Value
-
-
-
-
-
-
+
+
+
+
+
Name
+
Timestamp
+
Value
+
+
+
+
+
+
+
diff --git a/src/plugins/condition/components/ConditionCollection.vue b/src/plugins/condition/components/ConditionCollection.vue
new file mode 100644
index 00000000000..e96621f3d3d
--- /dev/null
+++ b/src/plugins/condition/components/ConditionCollection.vue
@@ -0,0 +1,245 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2020, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+
+
+
+
+
+
Conditions
+
+
+
+ Drag telemetry into this Condition Set to configure Conditions and add criteria.
+ The first condition to match is the one that is applied. Drag conditions to reorder.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/plugins/condition/components/ConditionDescription.vue b/src/plugins/condition/components/ConditionDescription.vue
new file mode 100644
index 00000000000..f80db911f14
--- /dev/null
+++ b/src/plugins/condition/components/ConditionDescription.vue
@@ -0,0 +1,145 @@
+/*****************************************************************************
+* Open MCT, Copyright (c) 2014-2020, United States Government
+* as represented by the Administrator of the National Aeronautics and Space
+* Administration. All rights reserved.
+*
+* Open MCT is licensed under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0.
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+* License for the specific language governing permissions and limitations
+* under the License.
+*
+* Open MCT includes source code licensed under additional open source
+* licenses. See the Open Source Licenses file (LICENSES.md) included with
+* this source code distribution or the Licensing information page available
+* at runtime from the About dialog for additional information.
+*****************************************************************************/
+
+
+
+
+
+
diff --git a/src/plugins/condition/components/ConditionError.vue b/src/plugins/condition/components/ConditionError.vue
new file mode 100644
index 00000000000..98f0e523d13
--- /dev/null
+++ b/src/plugins/condition/components/ConditionError.vue
@@ -0,0 +1,80 @@
+/*****************************************************************************
+* Open MCT, Copyright (c) 2014-2020, United States Government
+* as represented by the Administrator of the National Aeronautics and Space
+* Administration. All rights reserved.
+*
+* Open MCT is licensed under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0.
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+* License for the specific language governing permissions and limitations
+* under the License.
+*
+* Open MCT includes source code licensed under additional open source
+* licenses. See the Open Source Licenses file (LICENSES.md) included with
+* this source code distribution or the Licensing information page available
+* at runtime from the About dialog for additional information.
+*****************************************************************************/
+
+
+
+
+
+
diff --git a/src/plugins/condition/components/ConditionSet.vue b/src/plugins/condition/components/ConditionSet.vue
new file mode 100644
index 00000000000..d3ea6f49499
--- /dev/null
+++ b/src/plugins/condition/components/ConditionSet.vue
@@ -0,0 +1,97 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2020, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+
+
+
+
+
+
+
diff --git a/src/plugins/condition/components/Criterion.vue b/src/plugins/condition/components/Criterion.vue
new file mode 100644
index 00000000000..287b83127f2
--- /dev/null
+++ b/src/plugins/condition/components/Criterion.vue
@@ -0,0 +1,293 @@
+/*****************************************************************************
+* Open MCT, Copyright (c) 2014-2020, United States Government
+* as represented by the Administrator of the National Aeronautics and Space
+* Administration. All rights reserved.
+*
+* Open MCT is licensed under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0.
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+* License for the specific language governing permissions and limitations
+* under the License.
+*
+* Open MCT includes source code licensed under additional open source
+* licenses. See the Open Source Licenses file (LICENSES.md) included with
+* this source code distribution or the Licensing information page available
+* at runtime from the About dialog for additional information.
+*****************************************************************************/
+
+
+
+
+
+
diff --git a/src/plugins/condition/components/TestData.vue b/src/plugins/condition/components/TestData.vue
new file mode 100644
index 00000000000..24ac3ceb93f
--- /dev/null
+++ b/src/plugins/condition/components/TestData.vue
@@ -0,0 +1,237 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2020, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+
+
+
+
+
+
Test Data
+
+
+
+
+
+
+
+ Set
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/plugins/condition/components/condition-set.scss b/src/plugins/condition/components/condition-set.scss
new file mode 100644
index 00000000000..691091c36a1
--- /dev/null
+++ b/src/plugins/condition/components/condition-set.scss
@@ -0,0 +1,116 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2020, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+
+.c-cs {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ overflow: hidden;
+
+ &__content {
+ display: flex;
+ flex-direction: column;
+ flex: 0 1 auto;
+ overflow: hidden;
+
+ > * {
+ flex: 0 0 auto;
+ overflow: hidden;
+ + * {
+ margin-top: $interiorMarginSm;
+ }
+ }
+
+ .c-button {
+ align-self: start;
+ }
+ }
+
+ .is-editing & {
+ // Add some space to kick away from blue editing border indication
+ padding: $interiorMargin;
+ }
+
+ section {
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+ }
+
+ &__conditions-h {
+ display: flex;
+ flex-direction: column;
+ flex: 1 1 auto;
+ overflow: auto;
+ padding-right: $interiorMarginSm;
+
+ > * + * {
+ margin-top: $interiorMarginSm;
+ }
+ }
+
+ &__conditions {
+ > * + * {
+ margin-top: $interiorMarginSm;
+ }
+ }
+
+ .hint {
+ padding: $interiorMarginSm;
+ }
+
+ /************************** SPECIFIC ITEMS */
+ &__current-output-value {
+ font-size: 1.25em;
+ padding: $interiorMargin;
+ }
+}
+
+/***************************** TEST DATA */
+.c-cs-tests {
+ flex: 0 1 auto;
+ overflow: auto;
+ padding-right: $interiorMarginSm;
+
+ > * + * {
+ margin-top: $interiorMarginSm;
+ }
+}
+
+.c-cs-test {
+ > * {
+ flex: 0 0 auto;
+ + * {
+ margin-left: $interiorMargin;
+ }
+ }
+
+ &__controls {
+ display: flex;
+ flex: 1 1 auto;
+
+ > * + * {
+ margin-left: $interiorMargin;
+ }
+ }
+}
+
diff --git a/src/plugins/condition/components/condition.scss b/src/plugins/condition/components/condition.scss
new file mode 100644
index 00000000000..1f20e671466
--- /dev/null
+++ b/src/plugins/condition/components/condition.scss
@@ -0,0 +1,133 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2020, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+
+.c-condition,
+.c-test-datum {
+ @include discreteItem();
+ display: flex;
+ padding: $interiorMargin;
+
+ &--edit {
+ line-height: 160%; // For layout when inputs wrap, like in criteria
+ }
+}
+
+.c-condition {
+ flex-direction: column;
+ min-width: 400px;
+
+ > * + * {
+ margin-top: $interiorMarginSm;
+ }
+ &--browse {
+ .c-condition__summary {
+ border-top: 1px solid $colorInteriorBorder;
+ padding-top: $interiorMargin;
+ }
+ }
+
+ /***************************** HEADER */
+ &__header {
+ $h: 22px;
+ display: flex;
+ align-items: start;
+ align-content: stretch;
+ overflow: hidden;
+ min-height: $h;
+ line-height: $h;
+
+ > * {
+ flex: 0 0 auto;
+ + * {
+ margin-left: $interiorMarginSm;
+ }
+ }
+ }
+
+ &__drag-grippy {
+ transform: translateY(50%);
+ }
+
+ &__name {
+ font-weight: bold;
+ align-self: baseline; // Fixes bold line-height offset problem
+ }
+
+ &__output,
+ &__summary {
+ flex: 1 1 auto;
+ }
+}
+
+/***************************** CONDITION DEFINITION, EDITING */
+.c-cdef {
+ display: grid;
+ grid-row-gap: $interiorMarginSm;
+ grid-column-gap: $interiorMargin;
+ grid-auto-columns: min-content 1fr max-content;
+ align-items: start;
+ min-width: 150px;
+ margin-left: 29px;
+ overflow: hidden;
+
+ &__criteria,
+ &__match-and-criteria {
+ display: contents;
+ }
+
+ &__label {
+ grid-column: 1;
+ text-align: right;
+ white-space: nowrap;
+ }
+
+ &__separator {
+ grid-column: 1 / span 3;
+ }
+
+ &__controls {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: flex-start;
+ grid-column: 2;
+
+ > * > * {
+ margin-right: $interiorMarginSm;
+ }
+ }
+
+ &__buttons {
+ grid-column: 3;
+ }
+}
+
+.c-c__drag-ghost {
+ width: 100%;
+ min-height: $interiorMarginSm;
+
+ &.dragging {
+ min-height: 5em;
+ background-color: lightblue;
+ border-radius: 2px;
+ }
+
+}
diff --git a/src/plugins/condition/components/inspector/ConditionSetDialogTreeItem.vue b/src/plugins/condition/components/inspector/ConditionSetDialogTreeItem.vue
new file mode 100644
index 00000000000..7c3b189c9d5
--- /dev/null
+++ b/src/plugins/condition/components/inspector/ConditionSetDialogTreeItem.vue
@@ -0,0 +1,185 @@
+/*****************************************************************************
+* Open MCT, Copyright (c) 2014-2020, United States Government
+* as represented by the Administrator of the National Aeronautics and Space
+* Administration. All rights reserved.
+*
+* Open MCT is licensed under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0.
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+* License for the specific language governing permissions and limitations
+* under the License.
+*
+* Open MCT includes source code licensed under additional open source
+* licenses. See the Open Source Licenses file (LICENSES.md) included with
+* this source code distribution or the Licensing information page available
+* at runtime from the About dialog for additional information.
+*****************************************************************************/
+
+
+
+
+
+
+
+
{{ node.object.name }}
+
+
+
+
+
+ Loading...
+
+
+
+
+
+
+
+
diff --git a/src/plugins/condition/components/inspector/ConditionSetSelectorDialog.vue b/src/plugins/condition/components/inspector/ConditionSetSelectorDialog.vue
new file mode 100644
index 00000000000..38e241f96d1
--- /dev/null
+++ b/src/plugins/condition/components/inspector/ConditionSetSelectorDialog.vue
@@ -0,0 +1,172 @@
+/*****************************************************************************
+* Open MCT, Copyright (c) 2014-2020, United States Government
+* as represented by the Administrator of the National Aeronautics and Space
+* Administration. All rights reserved.
+*
+* Open MCT is licensed under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0.
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+* License for the specific language governing permissions and limitations
+* under the License.
+*
+* Open MCT includes source code licensed under additional open source
+* licenses. See the Open Source Licenses file (LICENSES.md) included with
+* this source code distribution or the Licensing information page available
+* at runtime from the About dialog for additional information.
+*****************************************************************************/
+
+
+
+
+
Select Condition Set
+
+
+
+
+
+
+
+
+
+
+
+ No results found
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/plugins/condition/components/inspector/ConditionalStylesView.vue b/src/plugins/condition/components/inspector/ConditionalStylesView.vue
new file mode 100644
index 00000000000..1b5d87349ef
--- /dev/null
+++ b/src/plugins/condition/components/inspector/ConditionalStylesView.vue
@@ -0,0 +1,335 @@
+/*****************************************************************************
+* Open MCT, Copyright (c) 2014-2020, United States Government
+* as represented by the Administrator of the National Aeronautics and Space
+* Administration. All rights reserved.
+*
+* Open MCT is licensed under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0.
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+* License for the specific language governing permissions and limitations
+* under the License.
+*
+* Open MCT includes source code licensed under additional open source
+* licenses. See the Open Source Licenses file (LICENSES.md) included with
+* this source code distribution or the Licensing information page available
+* at runtime from the About dialog for additional information.
+*****************************************************************************/
+
+
+
+
+
+
diff --git a/src/plugins/condition/components/inspector/StyleEditor.vue b/src/plugins/condition/components/inspector/StyleEditor.vue
new file mode 100644
index 00000000000..b830c1fc3d3
--- /dev/null
+++ b/src/plugins/condition/components/inspector/StyleEditor.vue
@@ -0,0 +1,179 @@
+/*****************************************************************************
+* Open MCT, Copyright (c) 2014-2020, United States Government
+* as represented by the Administrator of the National Aeronautics and Space
+* Administration. All rights reserved.
+*
+* Open MCT is licensed under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0.
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+* License for the specific language governing permissions and limitations
+* under the License.
+*
+* Open MCT includes source code licensed under additional open source
+* licenses. See the Open Source Licenses file (LICENSES.md) included with
+* this source code distribution or the Licensing information page available
+* at runtime from the About dialog for additional information.
+*****************************************************************************/
+
+
+
+
+
+ ABC
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/plugins/condition/components/inspector/conditional-styles.scss b/src/plugins/condition/components/inspector/conditional-styles.scss
new file mode 100644
index 00000000000..4033d27b016
--- /dev/null
+++ b/src/plugins/condition/components/inspector/conditional-styles.scss
@@ -0,0 +1,124 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2020, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+
+/********************************************* INSPECTOR STYLES TAB */
+.c-inspect-styles {
+ > * + * {
+ margin-top: $interiorMargin;
+ }
+
+ &__content,
+ &__conditions,
+ &__condition {
+ > * + * {
+ margin-top: $interiorMargin;
+ }
+ }
+
+ &__content {
+ display: flex;
+ flex-direction: column;
+ }
+
+ &__condition-set {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+
+ .c-object-label {
+ flex: 1 1 auto;
+ }
+
+ .c-button {
+ flex: 0 0 auto;
+ }
+ }
+
+ &__style,
+ &__condition {
+ padding: $interiorMargin;
+ }
+
+ &__condition {
+ @include discreteItem();
+ }
+
+ .c-style {
+ padding: 2px; // Allow a bit of room for thumb box-shadow
+
+ &__condition-desc {
+ @include ellipsize();
+ }
+ }
+}
+
+.c-inspect-styles__style {
+ .is-editing & {
+ border-bottom: 1px solid $colorInteriorBorder;
+ }
+}
+
+.l-shell:not(.is-editing) .c-inspect-styles {
+ .c-toolbar {
+ // Disabled-look toolbar when not editing
+ pointer-events: none;
+ cursor: inherit;
+
+ // Hide control buttons, like image URL
+ [class*='--image-url'] {
+ display: none;
+ }
+
+ // Make buttons look disabled by knocking back icon, not swatch element
+ .c-icon-button {
+ &:before {
+ opacity: $controlDisabledOpacity;
+ }
+ }
+ }
+}
+
+.c-toggle-styling-button {
+ display: none;
+
+ .is-editing & {
+ display: block;
+ align-self: flex-end;
+ }
+}
+
+.is-style-invisible {
+ display: none !important;
+
+ .is-editing & {
+ display: block !important;
+ opacity: 0.2;
+ }
+
+ &.c-style-thumb {
+ display: block !important;
+ background-color: transparent !important;
+ border-color: transparent !important;
+ @include bgCheckerboard($size: 10px, $imp: true);
+ opacity: 1;
+ }
+}
diff --git a/src/plugins/condition/criterion/AllTelemetryCriterion.js b/src/plugins/condition/criterion/AllTelemetryCriterion.js
new file mode 100644
index 00000000000..8355975d503
--- /dev/null
+++ b/src/plugins/condition/criterion/AllTelemetryCriterion.js
@@ -0,0 +1,172 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2020, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+
+import EventEmitter from 'EventEmitter';
+import {OPERATIONS} from '../utils/operations';
+import {computeCondition} from "@/plugins/condition/utils/evaluator";
+
+export default class TelemetryCriterion extends EventEmitter {
+
+ /**
+ * Subscribes/Unsubscribes to telemetry and emits the result
+ * of operations performed on the telemetry data returned and a given input value.
+ * @constructor
+ * @param telemetryDomainObjectDefinition {id: uuid, operation: enum, input: Array, metadata: string, key: {domainObject.identifier} }
+ * @param openmct
+ */
+ constructor(telemetryDomainObjectDefinition, openmct) {
+ super();
+
+ this.openmct = openmct;
+ this.objectAPI = this.openmct.objects;
+ this.telemetryAPI = this.openmct.telemetry;
+ this.timeAPI = this.openmct.time;
+ this.id = telemetryDomainObjectDefinition.id;
+ this.telemetry = telemetryDomainObjectDefinition.telemetry;
+ this.operation = telemetryDomainObjectDefinition.operation;
+ this.telemetryObjects = Object.assign({}, telemetryDomainObjectDefinition.telemetryObjects);
+ this.input = telemetryDomainObjectDefinition.input;
+ this.metadata = telemetryDomainObjectDefinition.metadata;
+ this.telemetryDataCache = {};
+ }
+
+ updateTelemetry(telemetryObjects) {
+ this.telemetryObjects = Object.assign({}, telemetryObjects);
+ }
+
+ formatData(data, telemetryObjects) {
+ if (data) {
+ this.telemetryDataCache[data.id] = this.computeResult(data);
+ }
+
+ let keys = Object.keys(telemetryObjects);
+ keys.forEach((key) => {
+ let telemetryObject = telemetryObjects[key];
+ const id = this.openmct.objects.makeKeyString(telemetryObject.identifier);
+ if (this.telemetryDataCache[id] === undefined) {
+ this.telemetryDataCache[id] = false;
+ }
+ });
+
+ const datum = {
+ result: computeCondition(this.telemetryDataCache, this.telemetry === 'all')
+ };
+
+ if (data) {
+ // TODO check back to see if we should format times here
+ this.timeAPI.getAllTimeSystems().forEach(timeSystem => {
+ datum[timeSystem.key] = data[timeSystem.key]
+ });
+ }
+ return datum;
+ }
+
+ handleSubscription(data, telemetryObjects) {
+ if(this.isValid()) {
+ this.emitEvent('criterionResultUpdated', this.formatData(data, telemetryObjects));
+ } else {
+ this.emitEvent('criterionResultUpdated', this.formatData({}, telemetryObjects));
+ }
+ }
+
+ findOperation(operation) {
+ for (let i=0; i < OPERATIONS.length; i++) {
+ if (operation === OPERATIONS[i].name) {
+ return OPERATIONS[i].operation;
+ }
+ }
+ return null;
+ }
+
+ computeResult(data) {
+ let result = false;
+ if (data) {
+ let comparator = this.findOperation(this.operation);
+ let params = [];
+ params.push(data[this.metadata]);
+ if (this.input instanceof Array && this.input.length) {
+ this.input.forEach(input => params.push(input));
+ }
+ if (typeof comparator === 'function') {
+ result = comparator(params);
+ }
+ }
+ return result;
+ }
+
+ emitEvent(eventName, data) {
+ this.emit(eventName, {
+ id: this.id,
+ data: data
+ });
+ }
+
+ isValid() {
+ return (this.telemetry === 'any' || this.telemetry === 'all') && this.metadata && this.operation;
+ }
+
+ requestLAD(options) {
+ options = Object.assign({},
+ options,
+ {
+ strategy: 'latest',
+ size: 1
+ }
+ );
+
+ if (!this.isValid()) {
+ return this.formatData({}, options.telemetryObjects);
+ }
+
+ const telemetryRequests = options.telemetryObjects
+ .map(telemetryObject => this.telemetryAPI.request(
+ telemetryObject,
+ options
+ ));
+
+ return Promise.all(telemetryRequests)
+ .then(telemetryRequestsResults => {
+ telemetryRequestsResults.forEach((results, index) => {
+ const latestDatum = results.length ? results[results.length - 1] : {};
+ if (index === telemetryRequestsResults.length-1) {
+ //when the last result is computed, we return the result
+ return {
+ id: this.id,
+ data: this.formatData(latestDatum, options.telemetryObjects)
+ };
+ } else {
+ if (latestDatum) {
+ this.telemetryDataCache[latestDatum.id] = this.computeResult(latestDatum);
+ }
+ }
+ });
+ });
+ }
+
+ destroy() {
+ this.emitEvent('criterionRemoved');
+ delete this.telemetryObjects;
+ delete this.telemetryDataCache;
+ delete this.telemetryObjectIdAsString;
+ delete this.telemetryObject;
+ }
+}
diff --git a/src/plugins/condition/criterion/TelemetryCriterion.js b/src/plugins/condition/criterion/TelemetryCriterion.js
new file mode 100644
index 00000000000..998e27431cd
--- /dev/null
+++ b/src/plugins/condition/criterion/TelemetryCriterion.js
@@ -0,0 +1,149 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2020, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+
+import EventEmitter from 'EventEmitter';
+import {OPERATIONS} from '../utils/operations';
+
+export default class TelemetryCriterion extends EventEmitter {
+
+ /**
+ * Subscribes/Unsubscribes to telemetry and emits the result
+ * of operations performed on the telemetry data returned and a given input value.
+ * @constructor
+ * @param telemetryDomainObjectDefinition {id: uuid, operation: enum, input: Array, metadata: string, key: {domainObject.identifier} }
+ * @param openmct
+ */
+ constructor(telemetryDomainObjectDefinition, openmct) {
+ super();
+
+ this.openmct = openmct;
+ this.objectAPI = this.openmct.objects;
+ this.telemetryAPI = this.openmct.telemetry;
+ this.timeAPI = this.openmct.time;
+ this.id = telemetryDomainObjectDefinition.id;
+ this.telemetry = telemetryDomainObjectDefinition.telemetry;
+ this.operation = telemetryDomainObjectDefinition.operation;
+ this.input = telemetryDomainObjectDefinition.input;
+ this.metadata = telemetryDomainObjectDefinition.metadata;
+ this.telemetryObject = telemetryDomainObjectDefinition.telemetryObject;
+ this.telemetryObjectIdAsString = this.objectAPI.makeKeyString(telemetryDomainObjectDefinition.telemetry);
+ this.on(`subscription:${this.telemetryObjectIdAsString}`, this.handleSubscription);
+ this.emitEvent('criterionUpdated', this);
+ }
+
+ updateTelemetry(telemetryObjects) {
+ this.telemetryObject = telemetryObjects[this.telemetryObjectIdAsString];
+ }
+
+ formatData(data) {
+ const datum = {
+ result: this.computeResult(data)
+ };
+
+ if (data) {
+ // TODO check back to see if we should format times here
+ this.timeAPI.getAllTimeSystems().forEach(timeSystem => {
+ datum[timeSystem.key] = data[timeSystem.key]
+ });
+ }
+ return datum;
+ }
+
+ handleSubscription(data) {
+ if(this.isValid()) {
+ this.emitEvent('criterionResultUpdated', this.formatData(data));
+ } else {
+ this.emitEvent('criterionResultUpdated', this.formatData({}));
+ }
+ }
+
+ findOperation(operation) {
+ for (let i=0, ii=OPERATIONS.length; i < ii; i++) {
+ if (operation === OPERATIONS[i].name) {
+ return OPERATIONS[i].operation;
+ }
+ }
+ return null;
+ }
+
+ computeResult(data) {
+ let result = false;
+ if (data) {
+ let comparator = this.findOperation(this.operation);
+ let params = [];
+ params.push(data[this.metadata]);
+ if (this.input instanceof Array && this.input.length) {
+ this.input.forEach(input => params.push(input));
+ }
+ if (typeof comparator === 'function') {
+ result = comparator(params);
+ }
+ }
+ return result;
+ }
+
+ emitEvent(eventName, data) {
+ this.emit(eventName, {
+ id: this.id,
+ data: data
+ });
+ }
+
+ isValid() {
+ return this.telemetryObject && this.metadata && this.operation;
+ }
+
+ requestLAD(options) {
+ options = Object.assign({},
+ options,
+ {
+ strategy: 'latest',
+ size: 1
+ }
+ );
+
+ if (!this.isValid()) {
+ return {
+ id: this.id,
+ data: this.formatData({})
+ };
+ }
+
+ return this.telemetryAPI.request(
+ this.telemetryObject,
+ options
+ ).then(results => {
+ const latestDatum = results.length ? results[results.length - 1] : {};
+ return {
+ id: this.id,
+ data: this.formatData(latestDatum)
+ };
+ });
+ }
+
+ destroy() {
+ this.off(`subscription:${this.telemetryObjectIdAsString}`, this.handleSubscription);
+ this.emitEvent('criterionRemoved');
+ delete this.telemetryObjectIdAsString;
+ delete this.telemetryObject;
+ }
+}
diff --git a/src/plugins/condition/criterion/TelemetryCriterionSpec.js b/src/plugins/condition/criterion/TelemetryCriterionSpec.js
new file mode 100644
index 00000000000..67c08c1165b
--- /dev/null
+++ b/src/plugins/condition/criterion/TelemetryCriterionSpec.js
@@ -0,0 +1,111 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2020, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+
+import TelemetryCriterion from "./TelemetryCriterion";
+
+let openmct = {},
+ mockListener,
+ testCriterionDefinition,
+ testTelemetryObject,
+ telemetryCriterion;
+
+describe("The telemetry criterion", function () {
+
+ beforeEach (() => {
+ testTelemetryObject = {
+ identifier:{ namespace: "", key: "test-object"},
+ type: "test-object",
+ name: "Test Object",
+ telemetry: {
+ valueMetadatas: [{
+ key: "value",
+ name: "Value",
+ hints: {
+ range: 2
+ }
+ },
+ {
+ key: "utc",
+ name: "Time",
+ format: "utc",
+ hints: {
+ domain: 1
+ }
+ }, {
+ key: "testSource",
+ source: "value",
+ name: "Test",
+ format: "enum"
+ }]
+ }
+ };
+ openmct.objects = jasmine.createSpyObj('objects', ['get', 'makeKeyString']);
+ openmct.objects.makeKeyString.and.returnValue(testTelemetryObject.identifier.key);
+ openmct.telemetry = jasmine.createSpyObj('telemetry', ['isTelemetryObject', "subscribe", "getMetadata", "getValueFormatter"]);
+ openmct.telemetry.isTelemetryObject.and.returnValue(true);
+ openmct.telemetry.subscribe.and.returnValue(function () {});
+ openmct.telemetry.getValueFormatter.and.returnValue({
+ parse: function (value) {
+ return value;
+ }
+ });
+ openmct.telemetry.getMetadata.and.returnValue(testTelemetryObject.telemetry);
+
+ openmct.time = jasmine.createSpyObj('timeAPI',
+ ['timeSystem', 'bounds', 'getAllTimeSystems']
+ );
+ openmct.time.timeSystem.and.returnValue({key: 'system'});
+ openmct.time.bounds.and.returnValue({start: 0, end: 1});
+ openmct.time.getAllTimeSystems.and.returnValue([{key: 'system'}]);
+
+ testCriterionDefinition = {
+ id: 'test-criterion-id',
+ telemetry: openmct.objects.makeKeyString(testTelemetryObject.identifier),
+ operation: 'lessThan',
+ metadata: 'sin',
+ telemetryObject: testTelemetryObject
+ };
+
+ mockListener = jasmine.createSpy('listener');
+
+ telemetryCriterion = new TelemetryCriterion(
+ testCriterionDefinition,
+ openmct
+ );
+
+ telemetryCriterion.on('criterionResultUpdated', mockListener);
+
+ });
+
+ it("initializes with a telemetry objectId as string", function () {
+ expect(telemetryCriterion.telemetryObjectIdAsString).toEqual(testTelemetryObject.identifier.key);
+ });
+
+ it("updates and emits event on new data from telemetry providers", function () {
+ spyOn(telemetryCriterion, 'emitEvent').and.callThrough();
+ telemetryCriterion.handleSubscription({
+ value: 'Hello',
+ utc: 'Hi'
+ });
+ expect(telemetryCriterion.emitEvent).toHaveBeenCalled();
+ });
+});
diff --git a/src/plugins/condition/plugin.js b/src/plugins/condition/plugin.js
new file mode 100644
index 00000000000..7239435ca66
--- /dev/null
+++ b/src/plugins/condition/plugin.js
@@ -0,0 +1,68 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2020, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+import ConditionSetViewProvider from './ConditionSetViewProvider.js';
+import ConditionSetCompositionPolicy from "./ConditionSetCompositionPolicy";
+import ConditionSetMetadataProvider from './ConditionSetMetadataProvider';
+import ConditionSetTelemetryProvider from './ConditionSetTelemetryProvider';
+import ConditionSetViewPolicy from './ConditionSetViewPolicy';
+import uuid from "uuid";
+
+export default function ConditionPlugin() {
+
+ return function install(openmct) {
+
+ openmct.types.addType('conditionSet', {
+ name: 'Condition Set',
+ key: 'conditionSet',
+ description: 'Monitor and evaluate telemetry values in real-time with a wide variety of criteria. Use to control the styling of many objects in Open MCT.',
+ creatable: true,
+ cssClass: 'icon-conditional',
+ initialize: function (domainObject) {
+ domainObject.configuration = {
+ conditionTestData: [],
+ conditionCollection: [{
+ isDefault: true,
+ id: uuid(),
+ configuration: {
+ name: 'Default',
+ output: 'Default',
+ trigger: 'all',
+ criteria: []
+ },
+ summary: 'Default condition'
+ }]
+ };
+ domainObject.composition = [];
+ domainObject.telemetry = {};
+ }
+ });
+ openmct.legacyExtension('policies', {
+ category: 'view',
+ implementation: ConditionSetViewPolicy
+ });
+ openmct.composition.addPolicy(new ConditionSetCompositionPolicy(openmct).allow);
+ openmct.telemetry.addProvider(new ConditionSetMetadataProvider(openmct));
+ openmct.telemetry.addProvider(new ConditionSetTelemetryProvider(openmct));
+ openmct.objectViews.addProvider(new ConditionSetViewProvider(openmct));
+
+ }
+}
diff --git a/src/plugins/condition/pluginSpec.js b/src/plugins/condition/pluginSpec.js
new file mode 100644
index 00000000000..664082b95e7
--- /dev/null
+++ b/src/plugins/condition/pluginSpec.js
@@ -0,0 +1,97 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2020, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+
+import { createOpenMct } from "testTools";
+import ConditionPlugin from "./plugin";
+
+let openmct = createOpenMct();
+openmct.install(new ConditionPlugin());
+
+let conditionSetDefinition;
+let mockConditionSetDomainObject;
+let element;
+let child;
+
+describe('the plugin', function () {
+
+ beforeAll((done) => {
+
+ conditionSetDefinition = openmct.types.get('conditionSet').definition;
+ const appHolder = document.createElement('div');
+ appHolder.style.width = '640px';
+ appHolder.style.height = '480px';
+
+ element = document.createElement('div');
+ child = document.createElement('div');
+ element.appendChild(child);
+
+ mockConditionSetDomainObject = {
+ identifier: {
+ key: 'testConditionSetKey',
+ namespace: ''
+ },
+ type: 'conditionSet'
+ };
+
+ conditionSetDefinition.initialize(mockConditionSetDomainObject);
+
+ openmct.on('start', done);
+ openmct.start(appHolder);
+ });
+
+ let mockConditionSetObject = {
+ name: 'Condition Set',
+ key: 'conditionSet',
+ creatable: true
+ };
+
+ it('defines a conditionSet object type with the correct key', () => {
+ expect(conditionSetDefinition.key).toEqual(mockConditionSetObject.key);
+ });
+
+ describe('the conditionSet object', () => {
+
+ it('is creatable', () => {
+ expect(conditionSetDefinition.creatable).toEqual(mockConditionSetObject.creatable);
+ });
+
+ it('initializes with an empty composition list', () => {
+ expect(mockConditionSetDomainObject.composition instanceof Array).toBeTrue();
+ expect(mockConditionSetDomainObject.composition.length).toEqual(0);
+ });
+
+ it('provides a view', () => {
+ const testViewObject = {
+ id:"test-object",
+ type: "conditionSet",
+ configuration: {
+ conditionCollection: []
+ }
+ };
+
+ const applicableViews = openmct.objectViews.get(testViewObject);
+ let conditionSetView = applicableViews.find((viewProvider) => viewProvider.key === 'conditionSet.view');
+ expect(conditionSetView).toBeDefined();
+ });
+
+ });
+});
diff --git a/src/plugins/condition/utils/constants.js b/src/plugins/condition/utils/constants.js
new file mode 100644
index 00000000000..9ccd08436e5
--- /dev/null
+++ b/src/plugins/condition/utils/constants.js
@@ -0,0 +1,54 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2020, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+
+export const TRIGGER = {
+ ANY: 'any',
+ ALL: 'all',
+ NOT: 'not',
+ XOR: 'xor'
+};
+
+export const TRIGGER_LABEL = {
+ 'any': 'when any criteria are met',
+ 'all': 'when all criteria are met',
+ 'not': 'when no criteria are met',
+ 'xor': 'when only one criteria is met'
+};
+
+export const STYLE_CONSTANTS = {
+ isStyleInvisible: 'is-style-invisible',
+ borderColorTitle: 'Set border color',
+ textColorTitle: 'Set text color',
+ backgroundColorTitle: 'Set background color',
+ imagePropertiesTitle: 'Edit image properties',
+ visibilityHidden: 'Hidden',
+ visibilityVisible: 'Visible'
+};
+
+export const ERROR = {
+ 'TELEMETRY_NOT_FOUND': {
+ errorText: 'Telemetry not found for criterion'
+ },
+ 'CONDITION_NOT_FOUND': {
+ errorText: 'Condition not found'
+ }
+};
diff --git a/src/plugins/condition/utils/evaluator.js b/src/plugins/condition/utils/evaluator.js
new file mode 100644
index 00000000000..7e2b70f7e23
--- /dev/null
+++ b/src/plugins/condition/utils/evaluator.js
@@ -0,0 +1,54 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2020, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+
+export const computeCondition = (resultMap, allMustBeTrue) => {
+ let result = false;
+ for (let key in resultMap) {
+ if (resultMap.hasOwnProperty(key)) {
+ result = resultMap[key];
+ if (allMustBeTrue && !result) {
+ //If we want all conditions to be true, then even one negative result should break.
+ break;
+ } else if (!allMustBeTrue && result) {
+ //If we want at least one condition to be true, then even one positive result should break.
+ break;
+ }
+ }
+ }
+ return result;
+};
+
+//Returns true only if limit number of results are satisfied
+export const computeConditionByLimit = (resultMap, limit) => {
+ let trueCount = 0;
+ for (let key in resultMap) {
+ if (resultMap.hasOwnProperty(key)) {
+ if (resultMap[key]) {
+ trueCount++;
+ }
+ if (trueCount > limit) {
+ break;
+ }
+ }
+ }
+ return trueCount === limit;
+};
diff --git a/src/plugins/condition/utils/evaluatorSpec.js b/src/plugins/condition/utils/evaluatorSpec.js
new file mode 100644
index 00000000000..132f77f181c
--- /dev/null
+++ b/src/plugins/condition/utils/evaluatorSpec.js
@@ -0,0 +1,66 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2020, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+
+import { computeConditionByLimit } from "./evaluator";
+
+describe('evaluate results based on trigger', function () {
+
+ it('should evaluate to true if trigger is NOT', () => {
+ const results = {
+ result: false,
+ result1: false,
+ result2: false
+ };
+ const result = computeConditionByLimit(results, 0);
+ expect(result).toBeTrue();
+ });
+
+ it('should evaluate to false if trigger is NOT', () => {
+ const results = {
+ result: true,
+ result1: false,
+ result2: false
+ };
+ const result = computeConditionByLimit(results, 0);
+ expect(result).toBeFalse();
+ });
+
+ it('should evaluate to true if trigger is XOR', () => {
+ const results = {
+ result: false,
+ result1: true,
+ result2: false
+ };
+ const result = computeConditionByLimit(results, 1);
+ expect(result).toBeTrue();
+ });
+
+ it('should evaluate to false if trigger is XOR', () => {
+ const results = {
+ result: false,
+ result1: true,
+ result2: true
+ };
+ const result = computeConditionByLimit(results, 1);
+ expect(result).toBeFalse();
+ });
+});
diff --git a/src/plugins/condition/utils/operations.js b/src/plugins/condition/utils/operations.js
new file mode 100644
index 00000000000..3026f887bd2
--- /dev/null
+++ b/src/plugins/condition/utils/operations.js
@@ -0,0 +1,276 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2020, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+
+import _ from 'lodash';
+
+export const OPERATIONS = [
+ {
+ name: 'equalTo',
+ operation: function (input) {
+ return Number(input[0]) === Number(input[1]);
+ },
+ text: 'is equal to',
+ appliesTo: ['number'],
+ inputCount: 1,
+ getDescription: function (values) {
+ return ' is ' + values.join(', ');
+ }
+ },
+ {
+ name: 'notEqualTo',
+ operation: function (input) {
+ return Number(input[0]) !== Number(input[1]);
+ },
+ text: 'is not equal to',
+ appliesTo: ['number'],
+ inputCount: 1,
+ getDescription: function (values) {
+ return ' is not ' + values.join(', ');
+ }
+ },
+ {
+ name: 'greaterThan',
+ operation: function (input) {
+ return Number(input[0]) > Number(input[1]);
+ },
+ text: 'is greater than',
+ appliesTo: ['number'],
+ inputCount: 1,
+ getDescription: function (values) {
+ return ' > ' + values.join(', ');
+ }
+ },
+ {
+ name: 'lessThan',
+ operation: function (input) {
+ return Number(input[0]) < Number(input[1]);
+ },
+ text: 'is less than',
+ appliesTo: ['number'],
+ inputCount: 1,
+ getDescription: function (values) {
+ return ' < ' + values.join(', ');
+ }
+ },
+ {
+ name: 'greaterThanOrEq',
+ operation: function (input) {
+ return Number(input[0]) >= Number(input[1]);
+ },
+ text: 'is greater than or equal to',
+ appliesTo: ['number'],
+ inputCount: 1,
+ getDescription: function (values) {
+ return ' >= ' + values.join(', ');
+ }
+ },
+ {
+ name: 'lessThanOrEq',
+ operation: function (input) {
+ return Number(input[0]) <= Number(input[1]);
+ },
+ text: 'is less than or equal to',
+ appliesTo: ['number'],
+ inputCount: 1,
+ getDescription: function (values) {
+ return ' <= ' + values.join(', ');
+ }
+ },
+ {
+ name: 'between',
+ operation: function (input) {
+ let numberInputs = [];
+ input.forEach(inputValue => numberInputs.push(Number(inputValue)));
+ let larger = Math.max(...numberInputs.slice(1,3));
+ let smaller = Math.min(...numberInputs.slice(1,3));
+ return (numberInputs[0] > smaller) && (numberInputs[0] < larger);
+ },
+ text: 'is between',
+ appliesTo: ['number'],
+ inputCount: 2,
+ getDescription: function (values) {
+ return ' is between ' + values[0] + ' and ' + values[1];
+ }
+ },
+ {
+ name: 'notBetween',
+ operation: function (input) {
+ let numberInputs = [];
+ input.forEach(inputValue => numberInputs.push(Number(inputValue)));
+ let larger = Math.max(...numberInputs.slice(1,3));
+ let smaller = Math.min(...numberInputs.slice(1,3));
+ return (numberInputs[0] < smaller) || (numberInputs[0] > larger);
+ },
+ text: 'is not between',
+ appliesTo: ['number'],
+ inputCount: 2,
+ getDescription: function (values) {
+ return ' is not between ' + values[0] + ' and ' + values[1];
+ }
+ },
+ {
+ name: 'textContains',
+ operation: function (input) {
+ return input[0] && input[1] && input[0].includes(input[1]);
+ },
+ text: 'text contains',
+ appliesTo: ['string'],
+ inputCount: 1,
+ getDescription: function (values) {
+ return ' contains ' + values.join(', ');
+ }
+ },
+ {
+ name: 'textDoesNotContain',
+ operation: function (input) {
+ return input[0] && input[1] && !input[0].includes(input[1]);
+ },
+ text: 'text does not contain',
+ appliesTo: ['string'],
+ inputCount: 1,
+ getDescription: function (values) {
+ return ' does not contain ' + values.join(', ');
+ }
+ },
+ {
+ name: 'textStartsWith',
+ operation: function (input) {
+ return input[0].startsWith(input[1]);
+ },
+ text: 'text starts with',
+ appliesTo: ['string'],
+ inputCount: 1,
+ getDescription: function (values) {
+ return ' starts with ' + values.join(', ');
+ }
+ },
+ {
+ name: 'textEndsWith',
+ operation: function (input) {
+ return input[0].endsWith(input[1]);
+ },
+ text: 'text ends with',
+ appliesTo: ['string'],
+ inputCount: 1,
+ getDescription: function (values) {
+ return ' ends with ' + values.join(', ');
+ }
+ },
+ {
+ name: 'textIsExactly',
+ operation: function (input) {
+ return input[0] === input[1];
+ },
+ text: 'text is exactly',
+ appliesTo: ['string'],
+ inputCount: 1,
+ getDescription: function (values) {
+ return ' is exactly ' + values.join(', ');
+ }
+ },
+ {
+ name: 'isUndefined',
+ operation: function (input) {
+ return typeof input[0] === 'undefined';
+ },
+ text: 'is undefined',
+ appliesTo: ['string', 'number', 'enum'],
+ inputCount: 0,
+ getDescription: function () {
+ return ' is undefined';
+ }
+ },
+ {
+ name: 'isDefined',
+ operation: function (input) {
+ return typeof input[0] !== 'undefined';
+ },
+ text: 'is defined',
+ appliesTo: ['string', 'number', 'enum'],
+ inputCount: 0,
+ getDescription: function () {
+ return ' is defined';
+ }
+ },
+ {
+ name: 'enumValueIs',
+ operation: function (input) {
+ return input[0] === input[1];
+ },
+ text: 'is',
+ appliesTo: ['enum'],
+ inputCount: 1,
+ getDescription: function (values) {
+ return ' is ' + values.join(', ');
+ }
+ },
+ {
+ name: 'enumValueIsNot',
+ operation: function (input) {
+ return input[0] !== input[1];
+ },
+ text: 'is not',
+ appliesTo: ['enum'],
+ inputCount: 1,
+ getDescription: function (values) {
+ return ' is not ' + values.join(', ');
+ }
+ },
+ {
+ name: 'valueIs',
+ operation: function (input) {
+ if (input[1]) {
+ const values = input[1].split(',');
+ return values.find((value) => input[0].toString() === _.trim(value.toString()));
+ }
+ return false;
+ },
+ text: 'is one of',
+ appliesTo: ["string", "number"],
+ inputCount: 1,
+ getDescription: function (values) {
+ return ' is one of ' + values[0];
+ }
+ },
+ {
+ name: 'valueIsNot',
+ operation: function (input) {
+ if (input[1]) {
+ const values = input[1].split(',');
+ const found = values.find((value) => input[0].toString() === _.trim(value.toString()));
+ return !found;
+ }
+ return false;
+ },
+ text: 'is not one of',
+ appliesTo: ["string", "number"],
+ inputCount: 1,
+ getDescription: function (values) {
+ return ' is not one of ' + values[0];
+ }
+ }
+];
+
+export const INPUT_TYPES = {
+ 'string': 'text',
+ 'number': 'number'
+};
diff --git a/src/plugins/condition/utils/operationsSpec.js b/src/plugins/condition/utils/operationsSpec.js
new file mode 100644
index 00000000000..23866551083
--- /dev/null
+++ b/src/plugins/condition/utils/operationsSpec.js
@@ -0,0 +1,90 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2020, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+
+import { OPERATIONS } from "./operations";
+let isOneOfOperation = OPERATIONS.find((operation) => operation.name === 'valueIs');
+let isNotOneOfOperation = OPERATIONS.find((operation) => operation.name === 'valueIsNot');
+let isBetween = OPERATIONS.find((operation) => operation.name === 'between');
+let isNotBetween = OPERATIONS.find((operation) => operation.name === 'notBetween');
+
+describe('Is one of and is not one of operations', function () {
+
+ it('should evaluate isOneOf to true for number inputs', () => {
+ const inputs = [45, "5,6,45,8"];
+ expect(!!isOneOfOperation.operation(inputs)).toBeTrue();
+ });
+
+ it('should evaluate isOneOf to true for string inputs', () => {
+ const inputs = ["45", " 45, 645, 4,8 "];
+ expect(!!isOneOfOperation.operation(inputs)).toBeTrue();
+ });
+
+ it('should evaluate isNotOneOf to true for number inputs', () => {
+ const inputs = [45, "5,6,4,8"];
+ expect(!!isNotOneOfOperation.operation(inputs)).toBeTrue();
+ });
+
+ it('should evaluate isNotOneOf to true for string inputs', () => {
+ const inputs = ["45", " 5,645, 4,8 "];
+ expect(!!isNotOneOfOperation.operation(inputs)).toBeTrue();
+ });
+
+ it('should evaluate isOneOf to false for number inputs', () => {
+ const inputs = [4, "5, 6, 7, 8"];
+ expect(!!isOneOfOperation.operation(inputs)).toBeFalse();
+ });
+
+ it('should evaluate isOneOf to false for string inputs', () => {
+ const inputs = ["4", "5,645 ,7,8"];
+ expect(!!isOneOfOperation.operation(inputs)).toBeFalse();
+ });
+
+ it('should evaluate isNotOneOf to false for number inputs', () => {
+ const inputs = [4, "5,4, 7,8"];
+ expect(!!isNotOneOfOperation.operation(inputs)).toBeFalse();
+ });
+
+ it('should evaluate isNotOneOf to false for string inputs', () => {
+ const inputs = ["4", "5,46,4,8"];
+ expect(!!isNotOneOfOperation.operation(inputs)).toBeFalse();
+ });
+
+ it('should evaluate isBetween to true', () => {
+ const inputs = ["4", "3", "89"];
+ expect(!!isBetween.operation(inputs)).toBeTrue();
+ });
+
+ it('should evaluate isNotBetween to true', () => {
+ const inputs = ["45", "100", "89"];
+ expect(!!isNotBetween.operation(inputs)).toBeTrue();
+ });
+
+ it('should evaluate isBetween to false', () => {
+ const inputs = ["4", "100", "89"];
+ expect(!!isBetween.operation(inputs)).toBeFalse();
+ });
+
+ it('should evaluate isNotBetween to false', () => {
+ const inputs = ["45", "30", "50"];
+ expect(!!isNotBetween.operation(inputs)).toBeFalse();
+ });
+});
diff --git a/src/plugins/condition/utils/styleUtils.js b/src/plugins/condition/utils/styleUtils.js
new file mode 100644
index 00000000000..10dcb986f16
--- /dev/null
+++ b/src/plugins/condition/utils/styleUtils.js
@@ -0,0 +1,45 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2020, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+
+export const getStyleProp = (key, defaultValue) => {
+ let styleProp = undefined;
+ switch(key) {
+ case 'fill': styleProp = {
+ backgroundColor: defaultValue || 'transparent'
+ };
+ break;
+ case 'stroke': styleProp = {
+ border: '1px solid ' + (defaultValue || 'transparent')
+ };
+ break;
+ case 'color': styleProp = {
+ color: defaultValue || 'transparent'
+ };
+ break;
+ case 'url': styleProp = {
+ imageUrl: defaultValue || 'transparent'
+ };
+ break;
+ }
+
+ return styleProp;
+};
diff --git a/src/plugins/conditionWidget/ConditionWidgetViewProvider.js b/src/plugins/conditionWidget/ConditionWidgetViewProvider.js
new file mode 100644
index 00000000000..d34af872d20
--- /dev/null
+++ b/src/plugins/conditionWidget/ConditionWidgetViewProvider.js
@@ -0,0 +1,64 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2020, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+
+import ConditionWidgetComponent from './components/ConditionWidget.vue';
+import Vue from 'vue';
+
+export default function ConditionWidget(openmct) {
+ return {
+ key: 'conditionWidget',
+ name: 'Condition Widget',
+ cssClass: 'icon-condition-widget',
+ canView: function (domainObject) {
+ return domainObject.type === 'conditionWidget';
+ },
+ canEdit: function (domainObject) {
+ return domainObject.type === 'conditionWidget';
+ },
+ view: function (domainObject) {
+ let component;
+
+ return {
+ show: function (element) {
+ component = new Vue({
+ el: element,
+ components: {
+ ConditionWidgetComponent: ConditionWidgetComponent
+ },
+ provide: {
+ openmct,
+ domainObject
+ },
+ template: ''
+ });
+ },
+ destroy: function (element) {
+ component.$destroy();
+ component = undefined;
+ }
+ };
+ },
+ priority: function () {
+ return 1;
+ }
+ };
+}
diff --git a/src/plugins/conditionWidget/components/ConditionWidget.vue b/src/plugins/conditionWidget/components/ConditionWidget.vue
new file mode 100644
index 00000000000..c6011eba255
--- /dev/null
+++ b/src/plugins/conditionWidget/components/ConditionWidget.vue
@@ -0,0 +1,55 @@
+/*****************************************************************************
+* Open MCT, Copyright (c) 2014-2020, United States Government
+* as represented by the Administrator of the National Aeronautics and Space
+* Administration. All rights reserved.
+*
+* Open MCT is licensed under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0.
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+* License for the specific language governing permissions and limitations
+* under the License.
+*
+* Open MCT includes source code licensed under additional open source
+* licenses. See the Open Source Licenses file (LICENSES.md) included with
+* this source code distribution or the Licensing information page available
+* at runtime from the About dialog for additional information.
+*****************************************************************************/
+
+
+
+
+
+
+
+
diff --git a/src/plugins/conditionWidget/components/condition-widget.scss b/src/plugins/conditionWidget/components/condition-widget.scss
new file mode 100644
index 00000000000..f25231aa880
--- /dev/null
+++ b/src/plugins/conditionWidget/components/condition-widget.scss
@@ -0,0 +1,58 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2020, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+
+.c-condition-widget {
+ $shdwSize: 3px;
+ @include userSelectNone();
+ background-color: rgba($colorBodyFg, 0.1); // Give a little presence if the user hasn't defined a fill color
+ border-radius: $basicCr;
+ border: 1px solid transparent;
+ display: inline-block;
+ padding: $interiorMarginLg $interiorMarginLg * 2;
+ cursor: inherit !important;
+ &[href] {
+ cursor: pointer !important;
+ }
+}
+
+// Make Condition Widget expand when in a hidden frame Layout context
+// For both static and Flexible Layouts
+.c-so-view--no-frame > .c-so-view__object-view > .c-condition-widget {
+ @include abs();
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0;
+}
+
+// Add some margin when a Condition Widget is in a Flexible Layout
+.c-fl .c-so-view--no-frame .c-condition-widget {
+ @include abs(1px);
+}
+
+// When the widget is in the main view, center it in the space
+.l-shell__main-container > .c-condition-widget {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+}
diff --git a/src/plugins/conditionWidget/plugin.js b/src/plugins/conditionWidget/plugin.js
new file mode 100644
index 00000000000..982700d2f4f
--- /dev/null
+++ b/src/plugins/conditionWidget/plugin.js
@@ -0,0 +1,58 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2020, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT is licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ * Open MCT includes source code licensed under additional open source
+ * licenses. See the Open Source Licenses file (LICENSES.md) included with
+ * this source code distribution or the Licensing information page available
+ * at runtime from the About dialog for additional information.
+ *****************************************************************************/
+
+import ConditionWidgetViewProvider from './ConditionWidgetViewProvider.js';
+
+export default function plugin() {
+ return function install(openmct) {
+ openmct.objectViews.addProvider(new ConditionWidgetViewProvider(openmct));
+
+ openmct.types.addType('conditionWidget', {
+ name: "Condition Widget",
+ description: "A button that can be used on its own, or dynamically styled with a Condition Set.",
+ creatable: true,
+ cssClass: 'icon-condition-widget',
+ initialize(domainObject) {
+ domainObject.label = 'Condition Widget';
+ },
+ form: [
+ {
+ "key": "label",
+ "name": "Label",
+ "control": "textfield",
+ property: [
+ "label"
+ ],
+ "required": true,
+ "cssClass": "l-input"
+ },
+ {
+ "key": "url",
+ "name": "URL",
+ "control": "textfield",
+ "required": false,
+ "cssClass": "l-input-lg"
+ }
+ ]
+ });
+ };
+}
diff --git a/src/plugins/displayLayout/DisplayLayoutToolbar.js b/src/plugins/displayLayout/DisplayLayoutToolbar.js
index 707c49327c1..f5cfa00fd10 100644
--- a/src/plugins/displayLayout/DisplayLayoutToolbar.js
+++ b/src/plugins/displayLayout/DisplayLayoutToolbar.js
@@ -347,78 +347,6 @@ define(['lodash'], function (_) {
};
}
- function getFillMenu(selectedParent, selection) {
- return {
- control: "color-picker",
- domainObject: selectedParent,
- applicableSelectedItems: selection.filter(selectionPath => {
- let type = selectionPath[0].context.layoutItem.type;
- return type === 'text-view' ||
- type === 'telemetry-view' ||
- type === 'box-view';
- }),
- property: function (selectionPath) {
- return getPath(selectionPath) + ".fill";
- },
- icon: "icon-paint-bucket",
- title: "Set fill color"
- };
- }
-
- function getStrokeMenu(selectedParent, selection) {
- return {
- control: "color-picker",
- domainObject: selectedParent,
- applicableSelectedItems: selection.filter(selectionPath => {
- let type = selectionPath[0].context.layoutItem.type;
- return type === 'text-view' ||
- type === 'telemetry-view' ||
- type === 'box-view' ||
- type === 'image-view' ||
- type === 'line-view';
- }),
- property: function (selectionPath) {
- return getPath(selectionPath) + ".stroke";
- },
- icon: "icon-line-horz",
- title: "Set border color"
- };
- }
-
- function getTextColorMenu(selectedParent, selection) {
- return {
- control: "color-picker",
- domainObject: selectedParent,
- applicableSelectedItems: selection.filter(selectionPath => {
- let type = selectionPath[0].context.layoutItem.type;
- return type === 'text-view' || type === 'telemetry-view';
- }),
- property: function (selectionPath) {
- return getPath(selectionPath) + ".color";
- },
- icon: "icon-font",
- mandatory: true,
- title: "Set text color",
- preventNone: true
- };
- }
-
- function getURLButton(selectedParent, selection) {
- return {
- control: "button",
- domainObject: selectedParent,
- applicableSelectedItems: selection.filter(selectionPath => {
- return selectionPath[0].context.layoutItem.type === 'image-view';
- }),
- property: function (selectionPath) {
- return getPath(selectionPath);
- },
- icon: "icon-image",
- title: "Edit image properties",
- dialog: DIALOG_FORM.image
- };
- }
-
function getTextButton(selectedParent, selection) {
return {
control: "button",
@@ -429,7 +357,7 @@ define(['lodash'], function (_) {
property: function (selectionPath) {
return getPath(selectionPath);
},
- icon: "icon-gear",
+ icon: "icon-font",
title: "Edit text properties",
dialog: DIALOG_FORM.text
};
@@ -505,14 +433,14 @@ define(['lodash'], function (_) {
let toolbar = {
'add-menu': [],
+ 'text': [],
+ 'url': [],
'toggle-frame': [],
'display-mode': [],
'telemetry-value': [],
'style': [],
'text-style': [],
'position': [],
- 'text': [],
- 'url': [],
'remove': []
};
@@ -550,15 +478,8 @@ define(['lodash'], function (_) {
if (toolbar['telemetry-value'].length === 0) {
toolbar['telemetry-value'] = [getTelemetryValueMenu(selectionPath, selectedObjects)];
}
- if (toolbar.style.length < 2) {
- toolbar.style = [
- getFillMenu(selectedParent, selectedObjects),
- getStrokeMenu(selectedParent, selectedObjects)
- ];
- }
if (toolbar['text-style'].length === 0) {
toolbar['text-style'] = [
- getTextColorMenu(selectedParent, selectedObjects),
getTextSizeMenu(selectedParent, selectedObjects)
];
}
@@ -575,15 +496,8 @@ define(['lodash'], function (_) {
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
}
} else if (layoutItem.type === 'text-view') {
- if (toolbar.style.length < 2) {
- toolbar.style = [
- getFillMenu(selectedParent, selectedObjects),
- getStrokeMenu(selectedParent, selectedObjects)
- ];
- }
if (toolbar['text-style'].length === 0) {
toolbar['text-style'] = [
- getTextColorMenu(selectedParent, selectedObjects),
getTextSizeMenu(selectedParent, selectedObjects)
];
}
@@ -603,12 +517,6 @@ define(['lodash'], function (_) {
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
}
} else if (layoutItem.type === 'box-view') {
- if (toolbar.style.length < 2) {
- toolbar.style = [
- getFillMenu(selectedParent, selectedObjects),
- getStrokeMenu(selectedParent, selectedObjects)
- ];
- }
if (toolbar.position.length === 0) {
toolbar.position = [
getStackOrder(selectedParent, selectionPath),
@@ -622,11 +530,6 @@ define(['lodash'], function (_) {
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
}
} else if (layoutItem.type === 'image-view') {
- if (toolbar.style.length === 0) {
- toolbar.style = [
- getStrokeMenu(selectedParent, selectedObjects)
- ];
- }
if (toolbar.position.length === 0) {
toolbar.position = [
getStackOrder(selectedParent, selectionPath),
@@ -636,18 +539,10 @@ define(['lodash'], function (_) {
getWidthInput(selectedParent, selectedObjects)
];
}
- if (toolbar.url.length === 0) {
- toolbar.url = [getURLButton(selectedParent, selectedObjects)];
- }
if (toolbar.remove.length === 0) {
toolbar.remove = [getRemoveButton(selectedParent, selectionPath, selectedObjects)];
}
} else if (layoutItem.type === 'line-view') {
- if (toolbar.style.length === 0) {
- toolbar.style = [
- getStrokeMenu(selectedParent, selectedObjects)
- ];
- }
if (toolbar.position.length === 0) {
toolbar.position = [
getStackOrder(selectedParent, selectionPath),
diff --git a/src/plugins/displayLayout/components/AlphanumericFormatView.vue b/src/plugins/displayLayout/components/AlphanumericFormatView.vue
index 2207d09d2cf..45dec6579f5 100644
--- a/src/plugins/displayLayout/components/AlphanumericFormatView.vue
+++ b/src/plugins/displayLayout/components/AlphanumericFormatView.vue
@@ -23,20 +23,20 @@