diff --git a/src/plugins/condition/components/inspector/StylesView.vue b/src/plugins/condition/components/inspector/StylesView.vue index dd783cda8a..07d9551d84 100644 --- a/src/plugins/condition/components/inspector/StylesView.vue +++ b/src/plugins/condition/components/inspector/StylesView.vue @@ -457,7 +457,7 @@ export default { domainObjects.forEach(domainObject => { let objectStyles = (domainObject.configuration && domainObject.configuration.objectStyles) || {}; this.removeConditionalStyles(objectStyles); - if (Object.keys(objectStyles).length <= 0) { + if (objectStyles && Object.keys(objectStyles).length <= 0) { objectStyles = undefined; } this.persist(domainObject, objectStyles); @@ -467,14 +467,14 @@ export default { this.items.forEach((item) => { const itemId = item.id; this.removeConditionalStyles(domainObjectStyles, itemId); - if (Object.keys(domainObjectStyles[itemId]).length <= 0) { + if (domainObjectStyles[itemId] && Object.keys(domainObjectStyles[itemId]).length <= 0) { delete domainObjectStyles[itemId]; } }); } else { this.removeConditionalStyles(domainObjectStyles); } - if (Object.keys(domainObjectStyles).length <= 0) { + if (domainObjectStyles && Object.keys(domainObjectStyles).length <= 0) { domainObjectStyles = undefined; } this.persist(this.domainObject, domainObjectStyles); @@ -553,9 +553,9 @@ export default { let itemConditionalStyle = { styles: []}; if (!this.conditionSetDomainObject) { if (domainObjectStyles[item.id] && domainObjectStyles[item.id].staticStyle) { - itemStaticStyle = domainObjectStyles[item.id].staticStyle.style; + itemStaticStyle = Object.assign({}, domainObjectStyles[item.id].staticStyle.style); } - if (item.applicableStyles[property]) { + if (item.applicableStyles[property] !== undefined) { itemStaticStyle[property] = this.staticStyle.style[property]; } if (Object.keys(itemStaticStyle).length <= 0) { diff --git a/src/plugins/condition/pluginSpec.js b/src/plugins/condition/pluginSpec.js index 93a1930bc4..75702df793 100644 --- a/src/plugins/condition/pluginSpec.js +++ b/src/plugins/condition/pluginSpec.js @@ -22,6 +22,9 @@ import { createOpenMct } from "testUtils"; import ConditionPlugin from "./plugin"; +import StylesView from "./components/inspector/StylesView.vue"; +import Vue from 'vue'; +import {getApplicableStylesForItem} from "./utils/styleUtils"; describe('the plugin', function () { let conditionSetDefinition; @@ -30,7 +33,7 @@ describe('the plugin', function () { let child; let openmct; - beforeAll((done) => { + beforeEach((done) => { openmct = createOpenMct(); openmct.install(new ConditionPlugin()); @@ -90,4 +93,259 @@ describe('the plugin', function () { }); }); + + describe('the condition set usage for multiple display layout items', () => { + let displayLayoutItem; + let lineLayoutItem; + let boxLayoutItem; + let selection; + let component; + let styleViewComponentObject; + const conditionSetDomainObject = { + "configuration":{ + "conditionTestData":[ + { + "telemetry":"", + "metadata":"", + "input":"" + } + ], + "conditionCollection":[ + { + "id":"39584410-cbf9-499e-96dc-76f27e69885d", + "configuration":{ + "name":"Unnamed Condition", + "output":"Sine > 0", + "trigger":"all", + "criteria":[ + { + "id":"85fbb2f7-7595-42bd-9767-a932266c5225", + "telemetry":{ + "namespace":"", + "key":"be0ba97f-b510-4f40-a18d-4ff121d5ea1a" + }, + "operation":"greaterThan", + "input":[ + "0" + ], + "metadata":"sin" + }, + { + "id":"35400132-63b0-425c-ac30-8197df7d5862", + "telemetry":"any", + "operation":"enumValueIs", + "input":[ + "0" + ], + "metadata":"state" + } + ] + }, + "summary":"Match if all criteria are met: Sine Wave Generator Sine > 0 and any telemetry State is OFF " + }, + { + "isDefault":true, + "id":"2532d90a-e0d6-4935-b546-3123522da2de", + "configuration":{ + "name":"Default", + "output":"Default", + "trigger":"all", + "criteria":[ + ] + }, + "summary":"" + } + ] + }, + "composition":[ + { + "namespace":"", + "key":"be0ba97f-b510-4f40-a18d-4ff121d5ea1a" + }, + { + "namespace":"", + "key":"077ffa67-e78f-4e99-80e0-522ac33a3888" + } + ], + "telemetry":{ + }, + "name":"Condition Set", + "type":"conditionSet", + "identifier":{ + "namespace":"", + "key":"863012c1-f6ca-4ab0-aed7-fd43d5e4cd12" + } + + }; + const staticStyle = { + "style":{ + "backgroundColor":"#717171", + "border":"1px solid #00ffff" + } + }; + const conditionalStyle = { + "conditionId":"39584410-cbf9-499e-96dc-76f27e69885d", + "style":{ + "isStyleInvisible":"", + "backgroundColor":"#717171", + "border":"1px solid #ffff00" + } + }; + + beforeEach(() => { + displayLayoutItem = { + "composition":[ + ], + "configuration":{ + "items":[ + { + "fill":"#717171", + "stroke":"", + "x":1, + "y":1, + "width":10, + "height":5, + "type":"box-view", + "id":"89b88746-d325-487b-aec4-11b79afff9e8" + }, + { + "x":18, + "y":9, + "x2":23, + "y2":4, + "stroke":"#717171", + "type":"line-view", + "id":"57d49a28-7863-43bd-9593-6570758916f0" + } + ], + "layoutGrid":[ + 10, + 10 + ] + }, + "name":"Display Layout", + "type":"layout", + "identifier":{ + "namespace":"", + "key":"c5e636c1-6771-4c9c-b933-8665cab189b3" + } + }; + lineLayoutItem = { + "x":18, + "y":9, + "x2":23, + "y2":4, + "stroke":"#717171", + "type":"line-view", + "id":"57d49a28-7863-43bd-9593-6570758916f0" + }; + boxLayoutItem = { + "fill": "#717171", + "stroke": "", + "x": 1, + "y": 1, + "width": 10, + "height": 5, + "type": "box-view", + "id": "89b88746-d325-487b-aec4-11b79afff9e8" + }; + selection = [ + [{ + context: { + "layoutItem": lineLayoutItem, + "index":1 + } + }, + { + context: { + "item": displayLayoutItem, + "supportsMultiSelect":true + } + }], + [{ + context: { + "layoutItem": boxLayoutItem, + "index": 0 + } + }, + { + context: { + item: displayLayoutItem, + "supportsMultiSelect":true + } + }] + ]; + let viewContainer = document.createElement('div'); + child.append(viewContainer); + component = new Vue({ + provide: { + openmct: openmct, + selection: selection + }, + el: viewContainer, + components: { + StylesView + }, + template: '' + }); + return Vue.nextTick().then(() => { + styleViewComponentObject = component.$root.$children[0]; + styleViewComponentObject.setEditState(true); + }); + }); + + it('initializes the items in the view', () => { + expect(styleViewComponentObject.items.length).toBe(2); + }); + + it('initializes conditional styles', () => { + styleViewComponentObject.conditionSetDomainObject = conditionSetDomainObject; + styleViewComponentObject.conditionalStyles = []; + styleViewComponentObject.initializeConditionalStyles(); + expect(styleViewComponentObject.conditionalStyles.length).toBe(2); + }); + + it('updates applicable conditional styles', () => { + styleViewComponentObject.conditionSetDomainObject = conditionSetDomainObject; + styleViewComponentObject.conditionalStyles = []; + styleViewComponentObject.initializeConditionalStyles(); + expect(styleViewComponentObject.conditionalStyles.length).toBe(2); + styleViewComponentObject.updateConditionalStyle(conditionalStyle, 'border'); + return Vue.nextTick().then(() => { + expect(styleViewComponentObject.domainObject.configuration.objectStyles).toBeDefined(); + [boxLayoutItem, lineLayoutItem].forEach((item) => { + const itemStyles = styleViewComponentObject.domainObject.configuration.objectStyles[item.id].styles; + expect(itemStyles.length).toBe(2); + const foundStyle = itemStyles.find((style) => { + return style.conditionId === conditionalStyle.conditionId; + }); + expect(foundStyle).toBeDefined(); + const applicableStyles = getApplicableStylesForItem(styleViewComponentObject.domainObject, item); + const applicableStylesKeys = Object.keys(applicableStyles).concat(['isStyleInvisible']); + Object.keys(foundStyle.style).forEach((key) => { + expect(applicableStylesKeys.indexOf(key)).toBeGreaterThan(-1); + expect(foundStyle.style[key]).toEqual(conditionalStyle.style[key]); + }); + }); + }); + }); + + it('updates applicable static styles', () => { + styleViewComponentObject.updateStaticStyle(staticStyle, 'border'); + return Vue.nextTick().then(() => { + expect(styleViewComponentObject.domainObject.configuration.objectStyles).toBeDefined(); + [boxLayoutItem, lineLayoutItem].forEach((item) => { + const itemStyle = styleViewComponentObject.domainObject.configuration.objectStyles[item.id].staticStyle; + expect(itemStyle).toBeDefined(); + const applicableStyles = getApplicableStylesForItem(styleViewComponentObject.domainObject, item); + const applicableStylesKeys = Object.keys(applicableStyles).concat(['isStyleInvisible']); + Object.keys(itemStyle.style).forEach((key) => { + expect(applicableStylesKeys.indexOf(key)).toBeGreaterThan(-1); + expect(itemStyle.style[key]).toEqual(staticStyle.style[key]); + }); + }); + }); + }); + + }); });