Compare commits
	
		
			33 Commits
		
	
	
		
			itc-mode-d
			...
			vista-r4.9
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 5f70ab7dd3 | ||
|   | 7f73e1e765 | ||
|   | ea7cf080c3 | ||
|   | 9b0762f201 | ||
|   | 31aa291672 | ||
|   | 65e8d8b23c | ||
|   | fdb35094f4 | ||
|   | 3b99a12d7f | ||
|   | 25ee2d8099 | ||
|   | c14cc25977 | ||
|   | 50997270e9 | ||
|   | 67e3094c6c | ||
|   | 526e31d10c | ||
|   | 3b316ed491 | ||
|   | 282ead581a | ||
|   | c4f18a4797 | ||
|   | c273e83093 | ||
|   | e4b9242864 | ||
|   | ceddadcac6 | ||
|   | 6e2437b09e | ||
|   | 5a44931537 | ||
|   | f165d9c064 | ||
|   | 613973d936 | ||
|   | 830f321f90 | ||
|   | a14cd62878 | ||
|   | 8314d03af5 | ||
|   | 187da3c462 | ||
|   | e4f134ca59 | ||
|   | 76829ad252 | ||
|   | a8da0d5917 | ||
|   | 488beb5b3f | ||
|   | 2f63718385 | ||
|   | 433f1bf28e | 
| @@ -1,5 +1,6 @@ | ||||
| import AutoCompleteField from './components/controls/AutoCompleteField.vue'; | ||||
| import ClockDisplayFormatField from './components/controls/ClockDisplayFormatField.vue'; | ||||
| import CheckBoxField from './components/controls/CheckBoxField.vue'; | ||||
| import Datetime from './components/controls/Datetime.vue'; | ||||
| import FileInput from './components/controls/FileInput.vue'; | ||||
| import Locator from './components/controls/Locator.vue'; | ||||
| @@ -12,6 +13,7 @@ import Vue from 'vue'; | ||||
|  | ||||
| export const DEFAULT_CONTROLS_MAP = { | ||||
|     'autocomplete': AutoCompleteField, | ||||
|     'checkbox': CheckBoxField, | ||||
|     'composite': ClockDisplayFormatField, | ||||
|     'datetime': Datetime, | ||||
|     'file-input': FileInput, | ||||
|   | ||||
| @@ -172,7 +172,9 @@ export default class FormsAPI { | ||||
|  | ||||
|         function onFormSave(save) { | ||||
|             return () => { | ||||
|                 overlay.dismiss(); | ||||
|                 if (overlay) { | ||||
|                     overlay.dismiss(); | ||||
|                 } | ||||
|  | ||||
|                 if (save) { | ||||
|                     save(changes); | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /***************************************************************************** | ||||
| * Open MCT, Copyright (c) 2014-2021, United States Government | ||||
| * Open MCT, Copyright (c) 2014-2022, United States Government | ||||
| * as represented by the Administrator of the National Aeronautics and Space | ||||
| * Administration. All rights reserved. | ||||
| * | ||||
| @@ -24,49 +24,60 @@ | ||||
| <div class="c-form"> | ||||
|     <div class="c-overlay__top-bar c-form__top-bar"> | ||||
|         <div class="c-overlay__dialog-title">{{ model.title }}</div> | ||||
|         <div class="c-overlay__dialog-hint hint">All fields marked <span class="req icon-asterisk"></span> are required.</div> | ||||
|         <div | ||||
|             v-if="hasRequiredFields" | ||||
|             class="c-overlay__dialog-hint hint" | ||||
|         >All fields marked <span class="req icon-asterisk"></span> are required.</div> | ||||
|     </div> | ||||
|     <form name="mctForm" | ||||
|           class="c-form__contents" | ||||
|           autocomplete="off" | ||||
|           @submit.prevent | ||||
|     <form | ||||
|         name="mctForm" | ||||
|         class="c-form__contents" | ||||
|         autocomplete="off" | ||||
|         @submit.prevent | ||||
|     > | ||||
|         <div v-for="section in formSections" | ||||
|              :key="section.id" | ||||
|              class="c-form__section" | ||||
|              :class="section.cssClass" | ||||
|         <div | ||||
|             v-for="section in formSections" | ||||
|             :key="section.id" | ||||
|             class="c-form__section" | ||||
|             :class="section.cssClass" | ||||
|         > | ||||
|             <h2 v-if="section.name" | ||||
|             <h2 | ||||
|                 v-if="section.name" | ||||
|                 class="c-form__section-header" | ||||
|             > | ||||
|                 {{ section.name }} | ||||
|             </h2> | ||||
|             <div v-for="(row, index) in section.rows" | ||||
|                  :key="row.id" | ||||
|                  class="u-contents" | ||||
|             <div | ||||
|                 v-for="(row, index) in section.rows" | ||||
|                 :key="row.id" | ||||
|                 class="u-contents" | ||||
|             > | ||||
|                 <FormRow :css-class="section.cssClass" | ||||
|                          :first="index < 1" | ||||
|                          :row="row" | ||||
|                          @onChange="onChange" | ||||
|                 <FormRow | ||||
|                     :css-class="section.cssClass" | ||||
|                     :first="index < 1" | ||||
|                     :row="row" | ||||
|                     @onChange="onChange" | ||||
|                 /> | ||||
|             </div> | ||||
|         </div> | ||||
|     </form> | ||||
|  | ||||
|     <div class="mct-form__controls c-overlay__button-bar c-form__bottom-bar"> | ||||
|         <button tabindex="0" | ||||
|                 :disabled="isInvalid" | ||||
|                 class="c-button c-button--major" | ||||
|                 @click="onSave" | ||||
|         <button | ||||
|             tabindex="0" | ||||
|             :disabled="isInvalid" | ||||
|             class="c-button c-button--major" | ||||
|             @click="onSave" | ||||
|         > | ||||
|             OK | ||||
|             {{ submitLabel }} | ||||
|         </button> | ||||
|         <button tabindex="0" | ||||
|                 class="c-button" | ||||
|                 @click="onDismiss" | ||||
|         <button | ||||
|             v-if="!hideCancel" | ||||
|             tabindex="0" | ||||
|             class="c-button" | ||||
|             @click="onDismiss" | ||||
|         > | ||||
|             Cancel | ||||
|             {{ cancelLabel }} | ||||
|         </button> | ||||
|     </div> | ||||
| </div> | ||||
| @@ -100,11 +111,42 @@ export default { | ||||
|         }; | ||||
|     }, | ||||
|     computed: { | ||||
|         hasRequiredFields() { | ||||
|             return this.model.sections.some(section => | ||||
|                 section.rows.some(row => row.required)); | ||||
|         }, | ||||
|         isInvalid() { | ||||
|             return Object.entries(this.invalidProperties) | ||||
|                 .some(([key, value]) => { | ||||
|                     return value; | ||||
|                 }); | ||||
|         }, | ||||
|         submitLabel() { | ||||
|             if ( | ||||
|                 this.model.buttons | ||||
|                 && this.model.buttons.submit | ||||
|                 && this.model.buttons.submit.label | ||||
|             ) { | ||||
|                 return this.model.buttons.submit.label; | ||||
|             } | ||||
|  | ||||
|             return 'OK'; | ||||
|         }, | ||||
|         cancelLabel() { | ||||
|             if ( | ||||
|                 this.model.buttons | ||||
|                 && this.model.buttons.cancel | ||||
|                 && this.model.buttons.cancel.label | ||||
|             ) { | ||||
|                 return this.model.buttons.submit.label; | ||||
|             } | ||||
|  | ||||
|             return 'Cancel'; | ||||
|         }, | ||||
|         hideCancel() { | ||||
|             return this.model.buttons | ||||
|                 && this.model.buttons.cancel | ||||
|                 && this.model.buttons.cancel.hide === true; | ||||
|         } | ||||
|     }, | ||||
|     mounted() { | ||||
|   | ||||
| @@ -75,10 +75,12 @@ export default { | ||||
|         rowClass() { | ||||
|             let cssClass = this.cssClass; | ||||
|  | ||||
|             if (this.row.required) { | ||||
|                 cssClass = `${cssClass} req`; | ||||
|             if (!this.row.required) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             cssClass = `${cssClass} req`; | ||||
|  | ||||
|             if (this.visited && this.valid !== undefined) { | ||||
|                 if (this.valid === true) { | ||||
|                     cssClass = `${cssClass} valid`; | ||||
|   | ||||
							
								
								
									
										62
									
								
								src/api/forms/components/controls/CheckBoxField.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/api/forms/components/controls/CheckBoxField.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| /***************************************************************************** | ||||
| * Open MCT, Copyright (c) 2014-2022, 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. | ||||
| *****************************************************************************/ | ||||
|  | ||||
| <template> | ||||
| <span class="form-control shell"> | ||||
|     <span | ||||
|         class="field control" | ||||
|         :class="model.cssClass" | ||||
|     > | ||||
|         <input | ||||
|             type="checkbox" | ||||
|             :checked="isChecked" | ||||
|             @input="toggleCheckBox" | ||||
|         > | ||||
|     </span> | ||||
| </span> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|     props: { | ||||
|         model: { | ||||
|             type: Object, | ||||
|             required: true | ||||
|         } | ||||
|     }, | ||||
|     data() { | ||||
|         return { | ||||
|             isChecked: this.model.value | ||||
|         }; | ||||
|     }, | ||||
|     methods: { | ||||
|         toggleCheckBox() { | ||||
|             this.isChecked = !this.isChecked; | ||||
|             const data = { | ||||
|                 model: this.model, | ||||
|                 value: this.isChecked | ||||
|             }; | ||||
|             this.$emit('onChange', data); | ||||
|         } | ||||
|     } | ||||
| }; | ||||
| </script> | ||||
| @@ -1,5 +1,5 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2021, United States Government | ||||
|  * Open MCT, Copyright (c) 2014-2022, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
| @@ -36,13 +36,14 @@ class InMemorySearchProvider { | ||||
|          */ | ||||
|         this.MAX_CONCURRENT_REQUESTS = 100; | ||||
|         /** | ||||
|         * If max results is not specified in query, use this as default. | ||||
|         */ | ||||
|          * If max results is not specified in query, use this as default. | ||||
|          */ | ||||
|         this.DEFAULT_MAX_RESULTS = 100; | ||||
|  | ||||
|         this.openmct = openmct; | ||||
|  | ||||
|         this.indexedIds = {}; | ||||
|         this.indexedCompositions = {}; | ||||
|         this.idsToIndex = []; | ||||
|         this.pendingIndex = {}; | ||||
|         this.pendingRequests = 0; | ||||
| @@ -58,7 +59,6 @@ class InMemorySearchProvider { | ||||
|         this.onWorkerMessageError = this.onWorkerMessageError.bind(this); | ||||
|         this.onerror = this.onWorkerError.bind(this); | ||||
|         this.startIndexing = this.startIndexing.bind(this); | ||||
|         this.onMutationOfIndexedObject = this.onMutationOfIndexedObject.bind(this); | ||||
|  | ||||
|         this.openmct.on('start', this.startIndexing); | ||||
|         this.openmct.on('destroy', () => { | ||||
| @@ -68,6 +68,9 @@ class InMemorySearchProvider { | ||||
|                 this.worker.port.onmessageerror = null; | ||||
|                 this.worker.port.close(); | ||||
|             } | ||||
|  | ||||
|             this.destroyObservers(this.indexedIds); | ||||
|             this.destroyObservers(this.indexedCompositions); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
| @@ -137,7 +140,7 @@ class InMemorySearchProvider { | ||||
|         }; | ||||
|         modelResults.hits = await Promise.all(event.data.results.map(async (hit) => { | ||||
|             const identifier = this.openmct.objects.parseKeyString(hit.keyString); | ||||
|             const domainObject = await this.openmct.objects.get(identifier.key); | ||||
|             const domainObject = await this.openmct.objects.get(identifier); | ||||
|  | ||||
|             return domainObject; | ||||
|         })); | ||||
| @@ -213,29 +216,52 @@ class InMemorySearchProvider { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     onMutationOfIndexedObject(domainObject) { | ||||
|     onNameMutation(domainObject, name) { | ||||
|         const provider = this; | ||||
|         provider.index(domainObject.identifier, domainObject); | ||||
|  | ||||
|         domainObject.name = name; | ||||
|         provider.index(domainObject); | ||||
|     } | ||||
|  | ||||
|     onCompositionMutation(domainObject, composition) { | ||||
|         const provider = this; | ||||
|         const indexedComposition = domainObject.composition; | ||||
|         const identifiersToIndex = composition | ||||
|             .filter(identifier => !indexedComposition | ||||
|                 .some(indexedIdentifier => this.openmct.objects | ||||
|                     .areIdsEqual([identifier, indexedIdentifier]))); | ||||
|  | ||||
|         identifiersToIndex.forEach(identifier => { | ||||
|             this.openmct.objects.get(identifier).then(objectToIndex => provider.index(objectToIndex)); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Pass an id and model to the worker to be indexed.  If the model has | ||||
|      * composition, schedule those ids for later indexing. | ||||
|      * Pass a domainObject to the worker to be indexed. | ||||
|      * If the object has composition, schedule those ids for later indexing. | ||||
|      * Watch for object changes and re-index object and children if so | ||||
|      * | ||||
|      * @private | ||||
|      * @param id a model id | ||||
|      * @param model a model | ||||
|      * @param domainObject a domainObject | ||||
|      */ | ||||
|     async index(id, domainObject) { | ||||
|     async index(domainObject) { | ||||
|         const provider = this; | ||||
|         const keyString = this.openmct.objects.makeKeyString(id); | ||||
|         const keyString = this.openmct.objects.makeKeyString(domainObject.identifier); | ||||
|  | ||||
|         if (!this.indexedIds[keyString]) { | ||||
|             this.openmct.objects.observe(domainObject, `*`, this.onMutationOfIndexedObject); | ||||
|             this.indexedIds[keyString] = this.openmct.objects.observe( | ||||
|                 domainObject, | ||||
|                 'name', | ||||
|                 this.onNameMutation.bind(this, domainObject) | ||||
|             ); | ||||
|             this.indexedCompositions[keyString] = this.openmct.objects.observe( | ||||
|                 domainObject, | ||||
|                 'composition', | ||||
|                 this.onCompositionMutation.bind(this, domainObject) | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         this.indexedIds[keyString] = true; | ||||
|  | ||||
|         if ((id.key !== 'ROOT')) { | ||||
|         if ((keyString !== 'ROOT')) { | ||||
|             if (this.worker) { | ||||
|                 this.worker.port.postMessage({ | ||||
|                     request: 'index', | ||||
| @@ -247,15 +273,12 @@ class InMemorySearchProvider { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         const composition = this.openmct.composition.registry.find(foundComposition => { | ||||
|             return foundComposition.appliesTo(domainObject); | ||||
|         }); | ||||
|         const composition = this.openmct.composition.get(domainObject); | ||||
|  | ||||
|         if (composition) { | ||||
|             const childIdentifiers = await composition.load(domainObject); | ||||
|             childIdentifiers.forEach(function (childIdentifier) { | ||||
|                 provider.scheduleForIndexing(childIdentifier); | ||||
|             }); | ||||
|         if (composition !== undefined) { | ||||
|             const children = await composition.load(); | ||||
|  | ||||
|             children.forEach(child => provider.scheduleForIndexing(child.identifier)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -271,12 +294,12 @@ class InMemorySearchProvider { | ||||
|         const provider = this; | ||||
|  | ||||
|         this.pendingRequests += 1; | ||||
|         const identifier = await this.openmct.objects.parseKeyString(keyString); | ||||
|         const domainObject = await this.openmct.objects.get(identifier.key); | ||||
|         const domainObject = await this.openmct.objects.get(keyString); | ||||
|         delete provider.pendingIndex[keyString]; | ||||
|  | ||||
|         try { | ||||
|             if (domainObject) { | ||||
|                 await provider.index(identifier, domainObject); | ||||
|                 await provider.index(domainObject); | ||||
|             } | ||||
|         } catch (error) { | ||||
|             console.warn('Failed to index domain object ' + keyString, error); | ||||
| @@ -305,9 +328,9 @@ class InMemorySearchProvider { | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|     * A local version of the same SharedWorker function | ||||
|     * if we don't have SharedWorkers available (e.g., iOS) | ||||
|     */ | ||||
|      * A local version of the same SharedWorker function | ||||
|      * if we don't have SharedWorkers available (e.g., iOS) | ||||
|      */ | ||||
|     localIndexItem(keyString, model) { | ||||
|         this.localIndexedItems[keyString] = { | ||||
|             type: model.type, | ||||
| @@ -347,6 +370,16 @@ class InMemorySearchProvider { | ||||
|         }; | ||||
|         this.onWorkerMessage(eventToReturn); | ||||
|     } | ||||
|  | ||||
|     destroyObservers(observers) { | ||||
|         Object.entries(observers).forEach(([keyString, unobserve]) => { | ||||
|             if (typeof unobserve === 'function') { | ||||
|                 unobserve(); | ||||
|             } | ||||
|  | ||||
|             delete observers[keyString]; | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|  | ||||
| export default InMemorySearchProvider; | ||||
|   | ||||
| @@ -33,8 +33,10 @@ | ||||
|  | ||||
|         port.onmessage = function (event) { | ||||
|             if (event.data.request === 'index') { | ||||
|                 console.log('onmessage index: ', event.data); | ||||
|                 indexItem(event.data.keyString, event.data.model); | ||||
|             } else if (event.data.request === 'search') { | ||||
|                 console.log('onmessage search: ', event.data); | ||||
|                 port.postMessage(search(event.data)); | ||||
|             } | ||||
|         }; | ||||
| @@ -77,6 +79,8 @@ | ||||
|             queryId: data.queryId | ||||
|         }; | ||||
|  | ||||
|         console.log('indexed on search: ', indexedItems); | ||||
|  | ||||
|         results = Object.values(indexedItems).filter((indexedItem) => { | ||||
|             return indexedItem.name.toLowerCase().includes(input); | ||||
|         }); | ||||
|   | ||||
| @@ -55,6 +55,11 @@ define([ | ||||
|      */ | ||||
|     function parseKeyString(keyString) { | ||||
|         if (isIdentifier(keyString)) { | ||||
|             // hack to workaround a bug mashing keyString into identifier.key | ||||
|             if (!keyString.namespace && keyString.key.includes(':')) { | ||||
|                 return parseKeyString(keyString.key); | ||||
|             } | ||||
|  | ||||
|             return keyString; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -25,6 +25,7 @@ import EventEmitter from 'EventEmitter'; | ||||
|  | ||||
| const ERRORS = { | ||||
|     TIMESYSTEM_KEY: 'All telemetry metadata must have a telemetry value with a key that matches the key of the active time system.', | ||||
|     TIMESYSTEM_KEY_NOTIFICATION: 'Telemetry metadata does not match the active time system.', | ||||
|     LOADED: 'Telemetry Collection has already been loaded.' | ||||
| }; | ||||
|  | ||||
| @@ -266,6 +267,10 @@ export class TelemetryCollection extends EventEmitter { | ||||
|         this.lastBounds = bounds; | ||||
|  | ||||
|         if (isTick) { | ||||
|             if (this.timeKey === undefined) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // need to check futureBuffer and need to check | ||||
|             // if anything has fallen out of bounds | ||||
|             let startIndex = 0; | ||||
| @@ -305,7 +310,6 @@ export class TelemetryCollection extends EventEmitter { | ||||
|             if (added.length > 0) { | ||||
|                 this.emit('add', added); | ||||
|             } | ||||
|  | ||||
|         } else { | ||||
|             // user bounds change, reset | ||||
|             this._reset(); | ||||
| @@ -325,12 +329,14 @@ export class TelemetryCollection extends EventEmitter { | ||||
|         let domains = this.metadata.valuesForHints(['domain']); | ||||
|         let domain = domains.find((d) => d.key === timeSystem.key); | ||||
|  | ||||
|         if (domain === undefined) { | ||||
|             this._error(ERRORS.TIMESYSTEM_KEY); | ||||
|         if (domain !== undefined) { | ||||
|             // timeKey is used to create a dummy datum used for sorting | ||||
|             this.timeKey = domain.source; | ||||
|         } else { | ||||
|             this._warn(ERRORS.TIMESYSTEM_KEY); | ||||
|             this.openmct.notifications.alert(ERRORS.TIMESYSTEM_KEY_NOTIFICATION) | ||||
|         } | ||||
|  | ||||
|         // timeKey is used to create a dummy datum used for sorting | ||||
|         this.timeKey = domain.source; // this defaults to key if no source is set | ||||
|          | ||||
|         let metadataValue = this.metadata.value(timeSystem.key) || { format: timeSystem.key }; | ||||
|         let valueFormatter = this.openmct.telemetry.getValueFormatter(metadataValue); | ||||
|  | ||||
| @@ -400,4 +406,8 @@ export class TelemetryCollection extends EventEmitter { | ||||
|     _error(message) { | ||||
|         throw new Error(message); | ||||
|     } | ||||
|  | ||||
|     _warn(message) { | ||||
|         console.warn(message); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -39,8 +39,10 @@ export default class ConditionSetViewProvider { | ||||
|         return isConditionSet && this.openmct.router.isNavigatedObject(objectPath); | ||||
|     } | ||||
|  | ||||
|     canEdit(domainObject) { | ||||
|         return domainObject.type === 'conditionSet'; | ||||
|     canEdit(domainObject, objectPath) { | ||||
|         const isConditionSet = domainObject.type === 'conditionSet'; | ||||
|  | ||||
|         return isConditionSet && this.openmct.router.isNavigatedObject(objectPath); | ||||
|     } | ||||
|  | ||||
|     view(domainObject, objectPath) { | ||||
|   | ||||
| @@ -66,10 +66,11 @@ export default class CreateAction extends PropertiesAction { | ||||
|         }); | ||||
|  | ||||
|         const parentDomainObject = parentDomainObjectPath[0]; | ||||
|         const namespace = parentDomainObject.identifier.namespace || parentDomainObject.key || ''; | ||||
|  | ||||
|         this.domainObject.modified = Date.now(); | ||||
|         this.domainObject.location = this.openmct.objects.makeKeyString(parentDomainObject.identifier); | ||||
|         this.domainObject.identifier.namespace = parentDomainObject.identifier.namespace; | ||||
|         this.domainObject.identifier.namespace = namespace; | ||||
|  | ||||
|         // Show saving progress dialog | ||||
|         let dialog = this.openmct.overlays.progressDialog({ | ||||
| @@ -99,6 +100,7 @@ export default class CreateAction extends PropertiesAction { | ||||
|      */ | ||||
|     async _navigateAndEdit(domainObject, parentDomainObjectpath) { | ||||
|         let objectPath; | ||||
|         let self = this; | ||||
|         if (parentDomainObjectpath) { | ||||
|             objectPath = parentDomainObjectpath && [domainObject].concat(parentDomainObjectpath); | ||||
|         } else { | ||||
| @@ -106,17 +108,22 @@ export default class CreateAction extends PropertiesAction { | ||||
|         } | ||||
|  | ||||
|         const url = '#/browse/' + objectPath | ||||
|             .map(object => object && this.openmct.objects.makeKeyString(object.identifier.key)) | ||||
|             .map(object => object && this.openmct.objects.makeKeyString(object.identifier)) | ||||
|             .reverse() | ||||
|             .join('/'); | ||||
|  | ||||
|         this.openmct.router.navigate(url); | ||||
|         function editObject() { | ||||
|             const objectView = self.openmct.objectViews.get(domainObject, objectPath)[0]; | ||||
|             const canEdit = objectView && objectView.canEdit && objectView.canEdit(domainObject, objectPath); | ||||
|  | ||||
|         const objectView = this.openmct.objectViews.get(domainObject, objectPath)[0]; | ||||
|         const canEdit = objectView && objectView.canEdit && objectView.canEdit(domainObject, objectPath); | ||||
|         if (canEdit) { | ||||
|             this.openmct.editor.edit(); | ||||
|             if (canEdit) { | ||||
|                 self.openmct.editor.edit(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         this.openmct.router.once('afterNavigation', editObject); | ||||
|  | ||||
|         this.openmct.router.navigate(url); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -65,13 +65,8 @@ export default { | ||||
|             keyString: undefined | ||||
|         }; | ||||
|     }, | ||||
|     computed: { | ||||
|         imageHistorySize() { | ||||
|             return this.imageHistory.length; | ||||
|         } | ||||
|     }, | ||||
|     watch: { | ||||
|         imageHistorySize(newSize, oldSize) { | ||||
|         imageHistory(newHistory, oldHistory) { | ||||
|             this.updatePlotImagery(); | ||||
|         } | ||||
|     }, | ||||
|   | ||||
| @@ -240,9 +240,6 @@ export default { | ||||
|         }; | ||||
|     }, | ||||
|     computed: { | ||||
|         imageHistorySize() { | ||||
|             return this.imageHistory.length; | ||||
|         }, | ||||
|         compassRoseSizingClasses() { | ||||
|             let compassRoseSizingClasses = ''; | ||||
|             if (this.sizedImageDimensions.width < 300) { | ||||
| @@ -409,19 +406,23 @@ export default { | ||||
|         } | ||||
|     }, | ||||
|     watch: { | ||||
|         imageHistorySize(newSize, oldSize) { | ||||
|             let imageIndex; | ||||
|             if (this.focusedImageTimestamp !== undefined) { | ||||
|                 const foundImageIndex = this.imageHistory.findIndex(image => { | ||||
|                     return image.time === this.focusedImageTimestamp; | ||||
|                 }); | ||||
|                 imageIndex = foundImageIndex > -1 ? foundImageIndex : newSize - 1; | ||||
|             } else { | ||||
|                 imageIndex = newSize > 0 ? newSize - 1 : undefined; | ||||
|             } | ||||
|         imageHistory: { | ||||
|             handler(newHistory, oldHistory) { | ||||
|                 const newSize = newHistory.length; | ||||
|                 let imageIndex; | ||||
|                 if (this.focusedImageTimestamp !== undefined) { | ||||
|                     const foundImageIndex = this.imageHistory.findIndex(image => { | ||||
|                         return image.time === this.focusedImageTimestamp; | ||||
|                     }); | ||||
|                     imageIndex = foundImageIndex > -1 ? foundImageIndex : newSize - 1; | ||||
|                 } else { | ||||
|                     imageIndex = newSize > 0 ? newSize - 1 : undefined; | ||||
|                 } | ||||
|  | ||||
|             this.setFocusedImage(imageIndex, false); | ||||
|             this.scrollToRight(); | ||||
|                 this.setFocusedImage(imageIndex, false); | ||||
|                 this.scrollToRight(); | ||||
|             }, | ||||
|             deep: true | ||||
|         }, | ||||
|         focusedImageIndex() { | ||||
|             this.trackDuration(); | ||||
| @@ -510,12 +511,6 @@ export default { | ||||
|                 this.timeContext.off("clock", this.trackDuration); | ||||
|             } | ||||
|         }, | ||||
|         boundsChange(bounds, isTick) { | ||||
|             if (!isTick) { | ||||
|                 this.previousFocusedImage = this.focusedImage ? JSON.parse(JSON.stringify(this.focusedImage)) : undefined; | ||||
|                 this.requestHistory(); | ||||
|             } | ||||
|         }, | ||||
|         expand() { | ||||
|             const actionCollection = this.openmct.actions.getActionsCollection(this.objectPath, this.currentView); | ||||
|             const visibleActions = actionCollection.getVisibleActions(); | ||||
| @@ -690,22 +685,32 @@ export default { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             if (this.previousFocusedImage) { | ||||
|                 // determine if the previous image exists in the new bounds of imageHistory | ||||
|                 const matchIndex = this.matchIndexOfPreviousImage( | ||||
|                     this.previousFocusedImage, | ||||
|                     this.imageHistory | ||||
|                 ); | ||||
|                 focusedIndex = matchIndex > -1 ? matchIndex : this.imageHistory.length - 1; | ||||
|  | ||||
|                 delete this.previousFocusedImage; | ||||
|             } | ||||
|  | ||||
|             if (thumbnailClick) { | ||||
|                 //We use the props till the user changes what they want to see | ||||
|                 this.focusedImageTimestamp = undefined; | ||||
|                 //set the previousFocusedImage when a user chooses an image | ||||
|                 this.previousFocusedImage = this.imageHistory[focusedIndex] ? JSON.parse(JSON.stringify(this.imageHistory[focusedIndex])) : undefined; | ||||
|             } | ||||
|  | ||||
|             if (this.previousFocusedImage) { | ||||
|                 // determine if the previous image exists in the new bounds of imageHistory | ||||
|                 if (!thumbnailClick) { | ||||
|                     const matchIndex = this.matchIndexOfPreviousImage( | ||||
|                         this.previousFocusedImage, | ||||
|                         this.imageHistory | ||||
|                     ); | ||||
|                     focusedIndex = matchIndex > -1 ? matchIndex : this.imageHistory.length - 1; | ||||
|                 } | ||||
|  | ||||
|                 if (!(this.isPaused || thumbnailClick) | ||||
|                     || focusedIndex === this.imageHistory.length - 1) { | ||||
|                     delete this.previousFocusedImage; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             this.focusedImageIndex = focusedIndex; | ||||
|  | ||||
|             //TODO: do we even need this anymore? | ||||
|             if (this.isPaused && !thumbnailClick && this.focusedImageTimestamp === undefined) { | ||||
|                 this.nextImageIndex = focusedIndex; | ||||
|                 //this could happen if bounds changes | ||||
| @@ -716,8 +721,6 @@ export default { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             this.focusedImageIndex = focusedIndex; | ||||
|  | ||||
|             if (thumbnailClick && !this.isPaused) { | ||||
|                 this.paused(true); | ||||
|             } | ||||
|   | ||||
| @@ -120,9 +120,15 @@ export default { | ||||
|             return this.timeFormatter.parse(datum); | ||||
|         }, | ||||
|         boundsChange(bounds, isTick) { | ||||
|             if (!isTick) { | ||||
|                 this.requestHistory(); | ||||
|             if (isTick) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // forcibly reset the imageContainer size to prevent an aspect ratio distortion | ||||
|             delete this.imageContainerWidth; | ||||
|             delete this.imageContainerHeight; | ||||
|  | ||||
|             return this.requestHistory(); | ||||
|         }, | ||||
|         async requestHistory() { | ||||
|             let bounds = this.timeContext.bounds(); | ||||
|   | ||||
| @@ -91,11 +91,11 @@ export default class LinkAction { | ||||
|     } | ||||
|  | ||||
|     validate(currentParent) { | ||||
|         return (object, data) => { | ||||
|             const parentCandidate = data.value; | ||||
|         return (data) => { | ||||
|             const parentCandidate = data.value[0]; | ||||
|             const currentParentKeystring = this.openmct.objects.makeKeyString(currentParent.identifier); | ||||
|             const parentCandidateKeystring = this.openmct.objects.makeKeyString(parentCandidate.identifier); | ||||
|             const objectKeystring = this.openmct.objects.makeKeyString(object.identifier); | ||||
|             const objectKeystring = this.openmct.objects.makeKeyString(this.object.identifier); | ||||
|  | ||||
|             if (!parentCandidateKeystring || !currentParentKeystring) { | ||||
|                 return false; | ||||
| @@ -114,7 +114,7 @@ export default class LinkAction { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             return parentCandidate && this.openmct.composition.checkPolicy(parentCandidate, object); | ||||
|             return parentCandidate && this.openmct.composition.checkPolicy(parentCandidate, this.object); | ||||
|         }; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -142,7 +142,6 @@ import { clearDefaultNotebook, getDefaultNotebook, setDefaultNotebook, setDefaul | ||||
| import { addNotebookEntry, createNewEmbed, getEntryPosById, getNotebookEntries, mutateObject } from '../utils/notebook-entries'; | ||||
| import { saveNotebookImageDomainObject, updateNamespaceOfDomainObject } from '../utils/notebook-image'; | ||||
| import { NOTEBOOK_VIEW_TYPE } from '../notebook-constants'; | ||||
| import objectUtils from 'objectUtils'; | ||||
|  | ||||
| import { debounce } from 'lodash'; | ||||
| import objectLink from '../../../ui/mixins/object-link'; | ||||
| @@ -455,11 +454,6 @@ export default { | ||||
|                 ? getDefaultNotebook().defaultSectionId | ||||
|                 : undefined; | ||||
|         }, | ||||
|         getDefaultNotebookObject() { | ||||
|             const defaultNotebook = getDefaultNotebook(); | ||||
|  | ||||
|             return defaultNotebook && this.openmct.objects.get(defaultNotebook.identifier); | ||||
|         }, | ||||
|         getLinktoNotebook() { | ||||
|             const objectPath = this.openmct.router.path; | ||||
|             const link = objectLink.computed.objectLink.call({ | ||||
| @@ -619,12 +613,12 @@ export default { | ||||
|  | ||||
|             this.sectionsChanged({ sections }); | ||||
|         }, | ||||
|         removeDefaultClass(domainObject) { | ||||
|             if (!domainObject) { | ||||
|         removeDefaultClass(defaultNotebookIdentifier) { | ||||
|             if (!defaultNotebookIdentifier) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             this.openmct.status.delete(domainObject.identifier); | ||||
|             this.openmct.status.delete(defaultNotebookIdentifier); | ||||
|         }, | ||||
|         resetSearch() { | ||||
|             this.search = ''; | ||||
| @@ -633,15 +627,16 @@ export default { | ||||
|         toggleNav() { | ||||
|             this.showNav = !this.showNav; | ||||
|         }, | ||||
|         async updateDefaultNotebook(notebookStorage) { | ||||
|             const defaultNotebookObject = await this.getDefaultNotebookObject(); | ||||
|             const isSameNotebook = defaultNotebookObject | ||||
|                 && objectUtils.makeKeyString(defaultNotebookObject.identifier) === objectUtils.makeKeyString(notebookStorage.identifier); | ||||
|         updateDefaultNotebook(notebookStorage) { | ||||
|             const defaultNotebook = getDefaultNotebook(); | ||||
|             const defaultNotebookIdentifier = defaultNotebook && defaultNotebook.identifier; | ||||
|             const isSameNotebook = defaultNotebookIdentifier | ||||
|                 && this.openmct.objects.areIdsEqual(defaultNotebookIdentifier, notebookStorage.identifier); | ||||
|             if (!isSameNotebook) { | ||||
|                 this.removeDefaultClass(defaultNotebookObject); | ||||
|                 this.removeDefaultClass(defaultNotebookIdentifier); | ||||
|             } | ||||
|  | ||||
|             if (!defaultNotebookObject || !isSameNotebook) { | ||||
|             if (!defaultNotebookIdentifier || !isSameNotebook) { | ||||
|                 setDefaultNotebook(this.openmct, notebookStorage, this.domainObject); | ||||
|             } | ||||
|  | ||||
|   | ||||
| @@ -110,7 +110,8 @@ export default class Snapshot { | ||||
|         } | ||||
|  | ||||
|         return () => { | ||||
|             window.location.href = window.location.origin + url; | ||||
|             const path = window.location.href.split('#'); | ||||
|             window.location.href = path[0] + url; | ||||
|         }; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -105,11 +105,6 @@ export function addNotebookEntry(openmct, domainObject, notebookStorage, embed = | ||||
|     const date = Date.now(); | ||||
|     const configuration = domainObject.configuration; | ||||
|     const entries = configuration.entries || {}; | ||||
|  | ||||
|     if (!entries) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     const embeds = embed | ||||
|         ? [embed] | ||||
|         : []; | ||||
| @@ -125,7 +120,8 @@ export function addNotebookEntry(openmct, domainObject, notebookStorage, embed = | ||||
|     const newEntries = addEntryIntoPage(notebookStorage, entries, entry); | ||||
|  | ||||
|     addDefaultClass(domainObject, openmct); | ||||
|     domainObject.configuration.entries = newEntries; | ||||
|  | ||||
|     mutateObject(openmct, domainObject, 'configuration.entries', newEntries); | ||||
|  | ||||
|     return id; | ||||
| } | ||||
|   | ||||
| @@ -278,7 +278,7 @@ export default { | ||||
|             // Have to throw away the old canvas elements and replace with new | ||||
|             // canvas elements in order to get new drawing contexts. | ||||
|             const div = document.createElement('div'); | ||||
|             div.innerHTML = this.TEMPLATE; | ||||
|             div.innerHTML = this.canvasTemplate + this.canvasTemplate; | ||||
|             const mainCanvas = div.querySelectorAll("canvas")[1]; | ||||
|             const overlayCanvas = div.querySelectorAll("canvas")[0]; | ||||
|             this.canvas.parentNode.replaceChild(mainCanvas, this.canvas); | ||||
|   | ||||
| @@ -29,10 +29,9 @@ define( | ||||
|         } | ||||
|  | ||||
|         SummaryWidgetsCompositionPolicy.prototype.allow = function (parent, child) { | ||||
|             const parentType = parent.getCapability('type'); | ||||
|             const newStyleChild = child.useCapability('adapter'); | ||||
|             const parentType = parent.type; | ||||
|  | ||||
|             if (parentType.instanceOf('summary-widget') && !this.openmct.telemetry.isTelemetryObject(newStyleChild)) { | ||||
|             if (parentType === 'summary-widget' && !this.openmct.telemetry.isTelemetryObject(child)) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|   | ||||
| @@ -21,7 +21,7 @@ | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| export const COLOR_PALETTE = [ | ||||
|     [0x00, 0x37, 0xFF], | ||||
|     [0x43, 0xB0, 0xFF], | ||||
|     [0xF0, 0x60, 0x00], | ||||
|     [0x00, 0x70, 0x40], | ||||
|     [0xFB, 0x49, 0x49], | ||||
| @@ -30,25 +30,25 @@ export const COLOR_PALETTE = [ | ||||
|     [0xFF, 0xA6, 0x3D], | ||||
|     [0x05, 0xA3, 0x00], | ||||
|     [0xF0, 0x00, 0x6C], | ||||
|     [0x77, 0x17, 0x7A], | ||||
|     [0xAC, 0x54, 0xAE], | ||||
|     [0x23, 0xA9, 0xDB], | ||||
|     [0xFA, 0xF0, 0x6F], | ||||
|     [0x4E, 0xF0, 0x48], | ||||
|     [0xC7, 0xBE, 0x52], | ||||
|     [0x5A, 0xBD, 0x56], | ||||
|     [0xAD, 0x50, 0x72], | ||||
|     [0x94, 0x25, 0xEA], | ||||
|     [0x21, 0x87, 0x82], | ||||
|     [0x8F, 0x6E, 0x47], | ||||
|     [0xf0, 0x59, 0xcb], | ||||
|     [0x34, 0xB6, 0x7D], | ||||
|     [0x6A, 0x36, 0xFF], | ||||
|     [0x56, 0xF0, 0xE8], | ||||
|     [0x7F, 0x52, 0xFF], | ||||
|     [0x46, 0xC7, 0xC0], | ||||
|     [0xA1, 0x8C, 0x1C], | ||||
|     [0xCB, 0xE1, 0x44], | ||||
|     [0x95, 0xB1, 0x26], | ||||
|     [0xFF, 0x84, 0x9E], | ||||
|     [0xB7, 0x79, 0xE7], | ||||
|     [0x8C, 0xC9, 0xFD], | ||||
|     [0xDB, 0xAA, 0x6E], | ||||
|     [0xB8, 0xDF, 0x97], | ||||
|     [0x93, 0xB5, 0x77], | ||||
|     [0xFF, 0xBC, 0xDA], | ||||
|     [0xD3, 0xB6, 0xDE] | ||||
| ]; | ||||
|   | ||||
| @@ -141,11 +141,15 @@ export default { | ||||
|             this.openmct.objectViews.off('clearData', this.clearData); | ||||
|         }, | ||||
|         getStyleReceiver() { | ||||
|             let styleReceiver = this.$refs.objectViewWrapper.querySelector('.js-style-receiver') | ||||
|                 || this.$refs.objectViewWrapper.querySelector(':first-child'); | ||||
|             let styleReceiver; | ||||
|  | ||||
|             if (styleReceiver === null) { | ||||
|                 styleReceiver = undefined; | ||||
|             if (this.$refs.objectViewWrapper !== undefined) { | ||||
|                 styleReceiver = this.$refs.objectViewWrapper.querySelector('.js-style-receiver') | ||||
|                   || this.$refs.objectViewWrapper.querySelector(':first-child'); | ||||
|  | ||||
|                 if (styleReceiver === null) { | ||||
|                     styleReceiver = undefined; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return styleReceiver; | ||||
|   | ||||
| @@ -186,6 +186,10 @@ export default { | ||||
|                     return { | ||||
|                         name: field.name, | ||||
|                         value: field.path.reduce((object, key) => { | ||||
|                             if (object === undefined) { | ||||
|                                 return object; | ||||
|                             } | ||||
|  | ||||
|                             return object[key]; | ||||
|                         }, this.domainObject) | ||||
|                     }; | ||||
|   | ||||
| @@ -445,6 +445,10 @@ export default { | ||||
|             } | ||||
|  | ||||
|             // sorting composition items | ||||
|             if (!a.name || !b.name) { | ||||
|                 return 0; | ||||
|             } | ||||
|  | ||||
|             if (a.name.toLowerCase() | ||||
|                 > b.name.toLowerCase()) { | ||||
|                 return 1; | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import objectPathToUrl from '/src/tools/url'; | ||||
| import objectPathToUrl from '../../tools/url'; | ||||
|  | ||||
| export default { | ||||
|     inject: ['openmct'], | ||||
|   | ||||
		Reference in New Issue
	
	Block a user