Compare commits
	
		
			11 Commits
		
	
	
		
			vue-3-memo
			...
			omm-r5.0.0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | faf71f1e67 | ||
|   | 23310f85ae | ||
|   | d80819634b | ||
|   | 483b62c152 | ||
|   | 1254279635 | ||
|   | c768a71656 | ||
|   | 678a92bd29 | ||
|   | 34b488944a | ||
|   | 4d1dd2f51d | ||
|   | 080f7b8f4b | ||
|   | 483f2feac8 | 
| @@ -55,6 +55,11 @@ define([ | ||||
|      */ | ||||
|     function parseKeyString(keyString) { | ||||
|         if (isIdentifier(keyString)) { | ||||
|             // TODO REMOVE FOR OMM-RELEASE-5.0 | ||||
|             if (!keyString.namespace && keyString.key.includes(':')) { | ||||
|                 console.error(`smushed key: ${keyString.key}`); | ||||
|             } | ||||
|  | ||||
|             return keyString; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -88,7 +88,7 @@ export default class TelemetryAPI { | ||||
|      * @memberof module:openmct.TelemetryAPI~TelemetryProvider# | ||||
|      */ | ||||
|     canProvideTelemetry(domainObject) { | ||||
|         return Boolean(this.#findSubscriptionProvider(domainObject)) | ||||
|         return Boolean(this.findSubscriptionProvider(domainObject)) | ||||
|                 || Boolean(this.findRequestProvider(domainObject)); | ||||
|     } | ||||
|  | ||||
| @@ -123,9 +123,10 @@ export default class TelemetryAPI { | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      * Returns a telemetry subscription provider that supports | ||||
|      * a given domain object and options. | ||||
|      */ | ||||
|     #findSubscriptionProvider() { | ||||
|     findSubscriptionProvider() { | ||||
|         const args = Array.prototype.slice.apply(arguments); | ||||
|         function supportsDomainObject(provider) { | ||||
|             return provider.supportsSubscribe.apply(provider, args); | ||||
| @@ -348,7 +349,7 @@ export default class TelemetryAPI { | ||||
|             return () => {}; | ||||
|         } | ||||
|  | ||||
|         const provider = this.#findSubscriptionProvider(domainObject); | ||||
|         const provider = this.findSubscriptionProvider(domainObject); | ||||
|  | ||||
|         if (!this.subscribeCache) { | ||||
|             this.subscribeCache = {}; | ||||
|   | ||||
| @@ -21,16 +21,18 @@ | ||||
| *****************************************************************************/ | ||||
|  | ||||
| <template> | ||||
| <component | ||||
|     :is="urlDefined ? 'a' : 'span'" | ||||
| <div | ||||
|     ref="conditionWidgetElement" | ||||
|     class="c-condition-widget u-style-receiver js-style-receiver" | ||||
|     :href="url" | ||||
|     :target="url ? '_BLANK' : ''" | ||||
| > | ||||
|     <div class="c-condition-widget__label"> | ||||
|         {{ label }} | ||||
|     </div> | ||||
| </component> | ||||
|     <component | ||||
|         :is="urlDefined ? 'a' : 'div'" | ||||
|         class="c-condition-widget__label-wrapper" | ||||
|         :href="url" | ||||
|     > | ||||
|         <div class="c-condition-widget__label">{{ label }}</div> | ||||
|     </component> | ||||
| </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| @@ -40,19 +42,26 @@ export default { | ||||
|     inject: ['openmct', 'domainObject'], | ||||
|     data: function () { | ||||
|         return { | ||||
|             conditionalLabel: '', | ||||
|             conditionSetIdentifier: null, | ||||
|             domainObjectLabel: '', | ||||
|             url: null, | ||||
|             urlDefined: false, | ||||
|             useConditionSetOutputAsLabel: false | ||||
|             conditionalLabel: '' | ||||
|         }; | ||||
|     }, | ||||
|     computed: { | ||||
|         urlDefined() { | ||||
|             return this.domainObject.url?.length > 0; | ||||
|         }, | ||||
|         url() { | ||||
|             return this.urlDefined ? sanitizeUrl(this.domainObject.url) : null; | ||||
|         }, | ||||
|         useConditionSetOutputAsLabel() { | ||||
|             return this.conditionSetIdentifier && this.domainObject.configuration.useConditionSetOutputAsLabel; | ||||
|         }, | ||||
|         conditionSetIdentifier() { | ||||
|             return this.domainObject.configuration?.objectStyles?.conditionSetIdentifier; | ||||
|         }, | ||||
|         label() { | ||||
|             return this.useConditionSetOutputAsLabel | ||||
|                 ? this.conditionalLabel | ||||
|                 : this.domainObjectLabel | ||||
|                 : this.domainObject.label | ||||
|             ; | ||||
|         } | ||||
|     }, | ||||
| @@ -69,20 +78,11 @@ export default { | ||||
|         } | ||||
|     }, | ||||
|     mounted() { | ||||
|         this.unlisten = this.openmct.objects.observe(this.domainObject, '*', this.updateDomainObject); | ||||
|  | ||||
|         if (this.domainObject) { | ||||
|             this.updateDomainObject(this.domainObject); | ||||
|             this.listenToConditionSetChanges(); | ||||
|         } | ||||
|     }, | ||||
|     beforeDestroy() { | ||||
|         this.conditionSetIdentifier = null; | ||||
|  | ||||
|         if (this.unlisten) { | ||||
|             this.unlisten(); | ||||
|         } | ||||
|  | ||||
|         this.stopListeningToConditionSetChanges(); | ||||
|     }, | ||||
|     methods: { | ||||
| @@ -121,31 +121,6 @@ export default { | ||||
|             } | ||||
|  | ||||
|             this.conditionalLabel = latestDatum.output || ''; | ||||
|         }, | ||||
|         updateDomainObject(domainObject) { | ||||
|             if (this.domainObjectLabel !== domainObject.label) { | ||||
|                 this.domainObjectLabel = domainObject.label; | ||||
|             } | ||||
|  | ||||
|             const urlDefined = domainObject.url && domainObject.url.length > 0; | ||||
|             if (this.urlDefined !== urlDefined) { | ||||
|                 this.urlDefined = urlDefined; | ||||
|             } | ||||
|  | ||||
|             const url = this.urlDefined ? sanitizeUrl(domainObject.url) : null; | ||||
|             if (this.url !== url) { | ||||
|                 this.url = url; | ||||
|             } | ||||
|  | ||||
|             const conditionSetIdentifier = domainObject.configuration?.objectStyles?.conditionSetIdentifier; | ||||
|             if (conditionSetIdentifier && this.conditionSetIdentifier !== conditionSetIdentifier) { | ||||
|                 this.conditionSetIdentifier = conditionSetIdentifier; | ||||
|             } | ||||
|  | ||||
|             const useConditionSetOutputAsLabel = this.conditionSetIdentifier && domainObject.configuration.useConditionSetOutputAsLabel; | ||||
|             if (this.useConditionSetOutputAsLabel !== useConditionSetOutputAsLabel) { | ||||
|                 this.useConditionSetOutputAsLabel = useConditionSetOutputAsLabel; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| }; | ||||
|   | ||||
| @@ -26,31 +26,35 @@ | ||||
|     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; | ||||
|     display: block; | ||||
|     max-width: max-content; | ||||
|  | ||||
|     a { | ||||
|         display: block; | ||||
|         color: inherit; | ||||
|     } | ||||
| } | ||||
|  | ||||
| .c-condition-widget__label { | ||||
|     padding: $interiorMargin; | ||||
|     // Either a <div> or an <a> tag | ||||
|     padding: $interiorMargin $interiorMargin * 1.5; | ||||
|     text-align: center; | ||||
|     white-space: normal; | ||||
| } | ||||
|  | ||||
| a.c-condition-widget { | ||||
|     // Widget is conditionally made into a <a> when URL property has been defined | ||||
|     cursor: pointer !important; | ||||
|     pointer-events: inherit; | ||||
| } | ||||
|  | ||||
| // Make Condition Widget expand when in a hidden frame Layout context | ||||
| // For both static and Flexible Layouts | ||||
| .c-so-view--conditionWidget.c-so-view--no-frame { | ||||
|     .c-condition-widget { | ||||
|         @include abs(); | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         justify-content: center; | ||||
|         padding: 0; | ||||
|         max-width: unset; | ||||
|  | ||||
|         &__label-wrapper { | ||||
|             @include abs(); | ||||
|             display: flex; | ||||
|             align-items: center; | ||||
|             justify-content: center; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     .c-so-view__frame-controls { display: none; } | ||||
|   | ||||
| @@ -36,6 +36,7 @@ export default function plugin() { | ||||
|                 domainObject.configuration = {}; | ||||
|                 domainObject.label = 'Condition Widget'; | ||||
|                 domainObject.conditionalLabel = ''; | ||||
|                 domainObject.url = ''; | ||||
|             }, | ||||
|             form: [ | ||||
|                 { | ||||
|   | ||||
| @@ -20,8 +20,6 @@ | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
| import JSONExporter from '/src/exporters/JSONExporter.js'; | ||||
|  | ||||
| import _ from 'lodash'; | ||||
| import { v4 as uuid } from 'uuid'; | ||||
|  | ||||
| export default class ExportAsJSONAction { | ||||
| @@ -35,10 +33,9 @@ export default class ExportAsJSONAction { | ||||
|         this.group = "json"; | ||||
|         this.priority = 1; | ||||
|  | ||||
|         this.externalIdentifiers = []; | ||||
|         this.tree = {}; | ||||
|         this.calls = 0; | ||||
|         this.idMap = {}; | ||||
|         this.tree = null; | ||||
|         this.calls = null; | ||||
|         this.idMap = null; | ||||
|  | ||||
|         this.JSONExportService = new JSONExporter(); | ||||
|     } | ||||
| @@ -60,21 +57,164 @@ export default class ExportAsJSONAction { | ||||
|      */ | ||||
|     invoke(objectpath) { | ||||
|         this.tree = {}; | ||||
|         this.calls = 0; | ||||
|         this.idMap = {}; | ||||
|  | ||||
|         const root = objectpath[0]; | ||||
|         this.root = JSON.parse(JSON.stringify(root)); | ||||
|         const rootId = this._getId(this.root); | ||||
|         this.root = this._copy(root); | ||||
|  | ||||
|         const rootId = this._getKeystring(this.root); | ||||
|         this.tree[rootId] = this.root; | ||||
|  | ||||
|         this._write(this.root); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      * @param {object} parent | ||||
|      */ | ||||
|     async _write(parent) { | ||||
|         this.calls++; | ||||
|  | ||||
|         //conditional object styles are not saved on the composition, so we need to check for them | ||||
|         const conditionSetIdentifier = this._getConditionSetIdentifier(parent); | ||||
|         const hasItemConditionSetIdentifiers = this._hasItemConditionSetIdentifiers(parent); | ||||
|         const composition = this.openmct.composition.get(parent); | ||||
|  | ||||
|         if (composition) { | ||||
|             const children = await composition.load(); | ||||
|  | ||||
|             children.forEach((child) => { | ||||
|                 this._exportObject(child, parent); | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         if (!conditionSetIdentifier && !hasItemConditionSetIdentifiers) { | ||||
|             this._decrementCallsAndSave(); | ||||
|         } else { | ||||
|             const conditionSetObjects = []; | ||||
|  | ||||
|             // conditionSetIdentifiers directly in objectStyles object | ||||
|             if (conditionSetIdentifier) { | ||||
|                 conditionSetObjects.push(await this.openmct.objects.get(conditionSetIdentifier)); | ||||
|             } | ||||
|  | ||||
|             // conditionSetIdentifiers stored on item ids in the objectStyles object | ||||
|             if (hasItemConditionSetIdentifiers) { | ||||
|                 const itemConditionSetIdentifiers = this._getItemConditionSetIdentifiers(parent); | ||||
|  | ||||
|                 for (const itemConditionSetIdentifier of itemConditionSetIdentifiers) { | ||||
|                     conditionSetObjects.push(await this.openmct.objects.get(itemConditionSetIdentifier)); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             for (const conditionSetObject of conditionSetObjects) { | ||||
|                 this._exportObject(conditionSetObject, parent); | ||||
|             } | ||||
|  | ||||
|             this._decrementCallsAndSave(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _exportObject(child, parent) { | ||||
|         const originalKeyString = this._getKeystring(child); | ||||
|         const createable = this._isCreatableAndPersistable(child); | ||||
|         const isNotInfinite = !Object.prototype.hasOwnProperty.call(this.tree, originalKeyString); | ||||
|  | ||||
|         if (createable && isNotInfinite) { | ||||
|             // for external or linked objects we generate new keys, if they don't exist already | ||||
|             if (this._isLinkedObject(child, parent)) { | ||||
|                 child = this._rewriteLink(child, parent); | ||||
|             } else { | ||||
|                 this.tree[originalKeyString] = child; | ||||
|             } | ||||
|  | ||||
|             this._write(child); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      * @param {object} child | ||||
|      * @param {object} parent | ||||
|      * @returns {object} | ||||
|      */ | ||||
|     _rewriteLink(child, parent) { | ||||
|         const originalKeyString = this._getKeystring(child); | ||||
|         const parentKeyString = this._getKeystring(parent); | ||||
|         const conditionSetIdentifier = this._getConditionSetIdentifier(parent); | ||||
|         const hasItemConditionSetIdentifiers = this._hasItemConditionSetIdentifiers(parent); | ||||
|         const existingMappedKeyString = this.idMap[originalKeyString]; | ||||
|         let copy; | ||||
|  | ||||
|         if (!existingMappedKeyString) { | ||||
|             copy = this._copy(child); | ||||
|             copy.identifier.key = uuid(); | ||||
|  | ||||
|             if (!conditionSetIdentifier && !hasItemConditionSetIdentifiers) { | ||||
|                 copy.location = parentKeyString; | ||||
|             } | ||||
|  | ||||
|             let newKeyString = this._getKeystring(copy); | ||||
|             this.idMap[originalKeyString] = newKeyString; | ||||
|             this.tree[newKeyString] = copy; | ||||
|         } else { | ||||
|             copy = this.tree[existingMappedKeyString]; | ||||
|         } | ||||
|  | ||||
|         if (conditionSetIdentifier || hasItemConditionSetIdentifiers) { | ||||
|  | ||||
|             // update objectStyle object | ||||
|             if (conditionSetIdentifier) { | ||||
|                 const directObjectStylesIdentifier = this.openmct.objects.areIdsEqual( | ||||
|                     parent.configuration.objectStyles.conditionSetIdentifier, | ||||
|                     child.identifier | ||||
|                 ); | ||||
|  | ||||
|                 if (directObjectStylesIdentifier) { | ||||
|                     parent.configuration.objectStyles.conditionSetIdentifier = copy.identifier; | ||||
|                     this.tree[parentKeyString].configuration.objectStyles.conditionSetIdentifier = copy.identifier; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // update per item id on objectStyle object | ||||
|             if (hasItemConditionSetIdentifiers) { | ||||
|                 for (const itemId in parent.configuration.objectStyles) { | ||||
|                     if (parent.configuration.objectStyles[itemId]) { | ||||
|                         const itemConditionSetIdentifier = parent.configuration.objectStyles[itemId].conditionSetIdentifier; | ||||
|  | ||||
|                         if ( | ||||
|                             itemConditionSetIdentifier | ||||
|                             && this.openmct.objects.areIdsEqual(itemConditionSetIdentifier, child.identifier) | ||||
|                         ) { | ||||
|                             parent.configuration.objectStyles[itemId].conditionSetIdentifier = copy.identifier; | ||||
|                             this.tree[parentKeyString].configuration.objectStyles[itemId].conditionSetIdentifier = copy.identifier; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             // just update parent | ||||
|             const index = parent.composition.findIndex(identifier => { | ||||
|                 return this.openmct.objects.areIdsEqual(child.identifier, identifier); | ||||
|             }); | ||||
|  | ||||
|             parent.composition[index] = copy.identifier; | ||||
|             this.tree[parentKeyString].composition[index] = copy.identifier; | ||||
|         } | ||||
|  | ||||
|         return copy; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      * @param {object} domainObject | ||||
|      * @returns {string} A string representation of the given identifier, including namespace and key | ||||
|      */ | ||||
|     _getId(domainObject) { | ||||
|     _getKeystring(domainObject) { | ||||
|         return this.openmct.objects.makeKeyString(domainObject.identifier); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      * @param {object} domainObject | ||||
| @@ -86,6 +226,7 @@ export default class ExportAsJSONAction { | ||||
|  | ||||
|         return type && type.definition.creatable && isPersistable; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      * @param {object} child | ||||
| @@ -93,74 +234,80 @@ export default class ExportAsJSONAction { | ||||
|      * @returns {boolean} | ||||
|      */ | ||||
|     _isLinkedObject(child, parent) { | ||||
|         if (child.location !== this._getId(parent) | ||||
|             && !Object.keys(this.tree).includes(child.location) | ||||
|             && this._getId(child) !== this._getId(this.root) | ||||
|             || this.externalIdentifiers.includes(this._getId(child))) { | ||||
|         const rootKeyString = this._getKeystring(this.root); | ||||
|         const childKeyString = this._getKeystring(child); | ||||
|         const parentKeyString = this._getKeystring(parent); | ||||
|  | ||||
|             return true; | ||||
|         return (child.location !== parentKeyString | ||||
|             && !Object.keys(this.tree).includes(child.location) | ||||
|             && childKeyString !== rootKeyString) | ||||
|             || this.idMap[childKeyString] !== undefined; | ||||
|     } | ||||
|  | ||||
|     _getConditionSetIdentifier(object) { | ||||
|         return object.configuration?.objectStyles?.conditionSetIdentifier; | ||||
|     } | ||||
|  | ||||
|     _hasItemConditionSetIdentifiers(parent) { | ||||
|         const objectStyles = parent.configuration?.objectStyles; | ||||
|  | ||||
|         for (const itemId in objectStyles) { | ||||
|             if (Object.prototype.hasOwnProperty.call(objectStyles[itemId], 'conditionSetIdentifier')) { | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
|     /** | ||||
|      * @private | ||||
|      * @param {object} child | ||||
|      * @param {object} parent | ||||
|      * @returns {object} | ||||
|      */ | ||||
|     _rewriteLink(child, parent) { | ||||
|         this.externalIdentifiers.push(this._getId(child)); | ||||
|         const index = parent.composition.findIndex(id => { | ||||
|             return _.isEqual(child.identifier, id); | ||||
|         }); | ||||
|         const copyOfChild = JSON.parse(JSON.stringify(child)); | ||||
|  | ||||
|         copyOfChild.identifier.key = uuid(); | ||||
|         const newIdString = this._getId(copyOfChild); | ||||
|         const parentId = this._getId(parent); | ||||
|     _getItemConditionSetIdentifiers(parent) { | ||||
|         const objectStyles = parent.configuration?.objectStyles; | ||||
|         let identifiers = new Set(); | ||||
|  | ||||
|         this.idMap[this._getId(child)] = newIdString; | ||||
|         copyOfChild.location = parentId; | ||||
|         parent.composition[index] = copyOfChild.identifier; | ||||
|         this.tree[newIdString] = copyOfChild; | ||||
|         this.tree[parentId].composition[index] = copyOfChild.identifier; | ||||
|         if (objectStyles) { | ||||
|             Object.keys(objectStyles).forEach(itemId => { | ||||
|                 if (objectStyles[itemId].conditionSetIdentifier) { | ||||
|                     identifiers.add(objectStyles[itemId].conditionSetIdentifier); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         return copyOfChild; | ||||
|         return Array.from(identifiers); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      * @param {object} child | ||||
|      * @param {object} parent | ||||
|      * @returns {object} | ||||
|      */ | ||||
|     _rewriteLinkForReference(child, parent) { | ||||
|         const childId = this._getId(child); | ||||
|         this.externalIdentifiers.push(childId); | ||||
|         const copyOfChild = JSON.parse(JSON.stringify(child)); | ||||
|  | ||||
|         copyOfChild.identifier.key = uuid(); | ||||
|         const newIdString = this._getId(copyOfChild); | ||||
|         const parentId = this._getId(parent); | ||||
|  | ||||
|         this.idMap[childId] = newIdString; | ||||
|         copyOfChild.location = null; | ||||
|         parent.configuration.objectStyles.conditionSetIdentifier = copyOfChild.identifier; | ||||
|         this.tree[newIdString] = copyOfChild; | ||||
|         this.tree[parentId].configuration.objectStyles.conditionSetIdentifier = copyOfChild.identifier; | ||||
|  | ||||
|         return copyOfChild; | ||||
|     } | ||||
|     /** | ||||
|      * @private | ||||
|      */ | ||||
|     _rewriteReferences() { | ||||
|         const oldKeyStrings = Object.keys(this.idMap); | ||||
|         let treeString = JSON.stringify(this.tree); | ||||
|         Object.keys(this.idMap).forEach(function (oldId) { | ||||
|             const newId = this.idMap[oldId]; | ||||
|             treeString = treeString.split(oldId).join(newId); | ||||
|         }.bind(this)); | ||||
|  | ||||
|         oldKeyStrings.forEach((oldKeyString) => { | ||||
|             // this will cover keyStrings, identifiers and identifiers created | ||||
|             // by hand that may be structured differently from those created with 'makeKeyString' | ||||
|             const newKeyString = this.idMap[oldKeyString]; | ||||
|             const newIdentifier = JSON.stringify(this.openmct.objects.parseKeyString(newKeyString)); | ||||
|             const oldIdentifier = this.openmct.objects.parseKeyString(oldKeyString); | ||||
|             const oldIdentifierNamespaceFirst = JSON.stringify(oldIdentifier); | ||||
|             const oldIdentifierKeyFirst = JSON.stringify({ | ||||
|                 key: oldIdentifier.key, | ||||
|                 namespace: oldIdentifier.namespace | ||||
|             }); | ||||
|  | ||||
|             // replace keyStrings | ||||
|             treeString = treeString.split(oldKeyString).join(newKeyString); | ||||
|  | ||||
|             // check for namespace first identifiers, replace if necessary | ||||
|             if (treeString.includes(oldIdentifierNamespaceFirst)) { | ||||
|                 treeString = treeString.split(oldIdentifierNamespaceFirst).join(newIdentifier); | ||||
|             } | ||||
|  | ||||
|             // check for key first identifiers, replace if necessary | ||||
|             if (treeString.includes(oldIdentifierKeyFirst)) { | ||||
|                 treeString = treeString.split(oldIdentifierKeyFirst).join(newIdentifier); | ||||
|             } | ||||
|  | ||||
|         }); | ||||
|         this.tree = JSON.parse(treeString); | ||||
|     } | ||||
|     /** | ||||
| @@ -180,70 +327,10 @@ export default class ExportAsJSONAction { | ||||
|     _wrapTree() { | ||||
|         return { | ||||
|             "openmct": this.tree, | ||||
|             "rootId": this._getId(this.root) | ||||
|             "rootId": this._getKeystring(this.root) | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      * @param {object} parent | ||||
|      */ | ||||
|     _write(parent) { | ||||
|         this.calls++; | ||||
|         //conditional object styles are not saved on the composition, so we need to check for them | ||||
|         let childObjectReferenceId = parent.configuration?.objectStyles?.conditionSetIdentifier; | ||||
|  | ||||
|         const composition = this.openmct.composition.get(parent); | ||||
|         if (composition !== undefined) { | ||||
|             composition.load() | ||||
|                 .then((children) => { | ||||
|                     children.forEach((child, index) => { | ||||
|                     // Only export if object is creatable | ||||
|                         if (this._isCreatableAndPersistable(child)) { | ||||
|                         // Prevents infinite export of self-contained objs | ||||
|                             if (!Object.prototype.hasOwnProperty.call(this.tree, this._getId(child))) { | ||||
|                             // If object is a link to something absent from | ||||
|                             // tree, generate new id and treat as new object | ||||
|                                 if (this._isLinkedObject(child, parent)) { | ||||
|                                     child = this._rewriteLink(child, parent); | ||||
|                                 } else { | ||||
|                                     this.tree[this._getId(child)] = child; | ||||
|                                 } | ||||
|  | ||||
|                                 this._write(child); | ||||
|                             } | ||||
|                         } | ||||
|                     }); | ||||
|                     this._decrementCallsAndSave(); | ||||
|                 }); | ||||
|         } else if (!childObjectReferenceId) { | ||||
|             this._decrementCallsAndSave(); | ||||
|         } | ||||
|  | ||||
|         if (childObjectReferenceId) { | ||||
|             this.openmct.objects.get(childObjectReferenceId) | ||||
|                 .then((child) => { | ||||
|                     // Only export if object is creatable | ||||
|                     if (this._isCreatableAndPersistable(child)) { | ||||
|                         // Prevents infinite export of self-contained objs | ||||
|                         if (!Object.prototype.hasOwnProperty.call(this.tree, this._getId(child))) { | ||||
|                             // If object is a link to something absent from | ||||
|                             // tree, generate new id and treat as new object | ||||
|                             if (this._isLinkedObject(child, parent)) { | ||||
|                                 child = this._rewriteLinkForReference(child, parent); | ||||
|                             } else { | ||||
|                                 this.tree[this._getId(child)] = child; | ||||
|                             } | ||||
|  | ||||
|                             this._write(child); | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     this._decrementCallsAndSave(); | ||||
|                 }); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _decrementCallsAndSave() { | ||||
|         this.calls--; | ||||
|         if (this.calls === 0) { | ||||
| @@ -251,4 +338,8 @@ export default class ExportAsJSONAction { | ||||
|             this._saveAs(this._wrapTree()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _copy(object) { | ||||
|         return JSON.parse(JSON.stringify(object)); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -64,6 +64,11 @@ export default class CreateAction extends PropertiesAction { | ||||
|  | ||||
|         const parentDomainObject = this.openmct.objects.toMutable(parentDomainObjectPath[0]); | ||||
|  | ||||
|         // TODO REMOVE FOR OMM-RELEASE-5.0 | ||||
|         if (!parentDomainObject.identifier.namespace && parentDomainObject.key) { | ||||
|             console.error(`parent namespace in key: ${parentDomainObject.key}`); | ||||
|         } | ||||
|  | ||||
|         this.domainObject.modified = Date.now(); | ||||
|         this.domainObject.location = this.openmct.objects.makeKeyString(parentDomainObject.identifier); | ||||
|         this.domainObject.identifier.namespace = parentDomainObject.identifier.namespace; | ||||
|   | ||||
| @@ -31,6 +31,7 @@ export default class ImportAsJSONAction { | ||||
|         this.cssClass = "icon-import"; | ||||
|         this.group = "json"; | ||||
|         this.priority = 2; | ||||
|         this.newObjects = []; | ||||
|  | ||||
|         this.openmct = openmct; | ||||
|     } | ||||
| @@ -85,22 +86,25 @@ export default class ImportAsJSONAction { | ||||
|         let objectIdentifiers = this._getObjectReferenceIds(parent); | ||||
|  | ||||
|         if (objectIdentifiers.length) { | ||||
|             let newObj; | ||||
|             const parentId = this.openmct.objects.makeKeyString(parent.identifier); | ||||
|             seen.push(parentId); | ||||
|  | ||||
|             seen.push(parent.id); | ||||
|  | ||||
|             objectIdentifiers.forEach(async (childId) => { | ||||
|             for (const childId of objectIdentifiers) { | ||||
|                 const keystring = this.openmct.objects.makeKeyString(childId); | ||||
|                 if (!tree[keystring] || seen.includes(keystring)) { | ||||
|                     return; | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 const newModel = tree[keystring]; | ||||
|                 delete newModel.persisted; | ||||
|  | ||||
|                 newObj = await this._instantiate(newModel); | ||||
|                 this._deepInstantiate(newObj, tree, seen); | ||||
|             }, this); | ||||
|                 this.newObjects.push(newModel); | ||||
|  | ||||
|                 // make sure there weren't any errors saving | ||||
|                 if (newModel) { | ||||
|                     this._deepInstantiate(newModel, tree, seen); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     /** | ||||
| @@ -110,19 +114,32 @@ export default class ImportAsJSONAction { | ||||
|      */ | ||||
|     _getObjectReferenceIds(parent) { | ||||
|         let objectIdentifiers = []; | ||||
|         let itemObjectReferences = []; | ||||
|         const objectStyles = parent?.configuration?.objectStyles; | ||||
|         const parentComposition = this.openmct.composition.get(parent); | ||||
|  | ||||
|         let parentComposition = this.openmct.composition.get(parent); | ||||
|         if (parentComposition) { | ||||
|             objectIdentifiers = Array.from(parentComposition.domainObject.composition); | ||||
|             objectIdentifiers = Array.from(parent.composition); | ||||
|         } | ||||
|  | ||||
|         //conditional object styles are not saved on the composition, so we need to check for them | ||||
|         let parentObjectReference = parent.configuration?.objectStyles?.conditionSetIdentifier; | ||||
|         if (parentObjectReference) { | ||||
|             objectIdentifiers.push(parentObjectReference); | ||||
|         if (objectStyles) { | ||||
|             const parentObjectReference = objectStyles.conditionSetIdentifier; | ||||
|  | ||||
|             if (parentObjectReference) { | ||||
|                 objectIdentifiers.push(parentObjectReference); | ||||
|             } | ||||
|  | ||||
|             function hasConditionSetIdentifier(item) { | ||||
|                 return Boolean(item.conditionSetIdentifier); | ||||
|             } | ||||
|  | ||||
|             itemObjectReferences = Object.values(objectStyles) | ||||
|                 .filter(hasConditionSetIdentifier) | ||||
|                 .map(item => item.conditionSetIdentifier); | ||||
|         } | ||||
|  | ||||
|         return objectIdentifiers; | ||||
|         return Array.from(new Set([...objectIdentifiers, ...itemObjectReferences])); | ||||
|     } | ||||
|     /** | ||||
|      * @private | ||||
| @@ -155,13 +172,21 @@ export default class ImportAsJSONAction { | ||||
|         const tree = this._generateNewIdentifiers(objTree, namespace); | ||||
|         const rootId = tree.rootId; | ||||
|  | ||||
|         const rootModel = tree.openmct[rootId]; | ||||
|         delete rootModel.persisted; | ||||
|         const rootObj = tree.openmct[rootId]; | ||||
|         delete rootObj.persisted; | ||||
|         this.newObjects.push(rootObj); | ||||
|  | ||||
|         const rootObj = await this._instantiate(rootModel); | ||||
|         if (this.openmct.composition.checkPolicy(domainObject, rootObj)) { | ||||
|             this._deepInstantiate(rootObj, tree.openmct, []); | ||||
|  | ||||
|             try { | ||||
|                 await Promise.all(this.newObjects.map(this._instantiate, this)); | ||||
|             } catch (error) { | ||||
|                 this.openmct.notifications.error('Error saving objects'); | ||||
|  | ||||
|                 throw error; | ||||
|             } | ||||
|  | ||||
|             const compositionCollection = this.openmct.composition.get(domainObject); | ||||
|             let domainObjectKeyString = this.openmct.objects.makeKeyString(domainObject.identifier); | ||||
|             this.openmct.objects.mutate(rootObj, 'location', domainObjectKeyString); | ||||
| @@ -184,16 +209,11 @@ export default class ImportAsJSONAction { | ||||
|     } | ||||
|     /** | ||||
|      * @private | ||||
|      * @param {object} rootModel | ||||
|      * @param {object} model | ||||
|      * @returns {object} | ||||
|      */ | ||||
|     async _instantiate(rootModel) { | ||||
|         const success = await this.openmct.objects.save(rootModel); | ||||
|         if (success) { | ||||
|             return rootModel; | ||||
|         } | ||||
|  | ||||
|         this.openmct.notifications.error('Error saving objects'); | ||||
|     _instantiate(model) { | ||||
|         return this.openmct.objects.save(model); | ||||
|     } | ||||
|     /** | ||||
|      * @private | ||||
|   | ||||
| @@ -19,7 +19,7 @@ | ||||
|             class="c-icon-button c-button--menu icon-font" | ||||
|             @click.prevent.stop="showFontMenu" | ||||
|         > | ||||
|             <span class="c-button__label">{{ fontTypeLable }}</span> | ||||
|             <span class="c-button__label">{{ fontTypeLabel }}</span> | ||||
|         </button> | ||||
|     </div> | ||||
| </div> | ||||
| @@ -43,7 +43,7 @@ export default { | ||||
|         } | ||||
|     }, | ||||
|     computed: { | ||||
|         fontTypeLable() { | ||||
|         fontTypeLabel() { | ||||
|             const fontType = FONTS.find(f => f.value === this.fontStyle.font); | ||||
|             if (!fontType) { | ||||
|                 return '??'; | ||||
|   | ||||
| @@ -88,7 +88,7 @@ define([], function () { | ||||
|         } | ||||
|  | ||||
|         getContextMenuActions() { | ||||
|             return ['viewDatumAction']; | ||||
|             return ['viewDatumAction', 'viewHistoricalData']; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -175,14 +175,22 @@ export default { | ||||
|         getDatum() { | ||||
|             return this.row.fullDatum; | ||||
|         }, | ||||
|         showContextMenu: function (event) { | ||||
|         showContextMenu: async function (event) { | ||||
|             event.preventDefault(); | ||||
|  | ||||
|             this.updateViewContext(); | ||||
|             this.markRow(event); | ||||
|  | ||||
|             const contextualDomainObject = await this.row.getContextualDomainObject?.(this.openmct, this.row.objectKeyString); | ||||
|  | ||||
|             let objectPath = this.objectPath; | ||||
|             if (contextualDomainObject) { | ||||
|                 objectPath = objectPath.slice(); | ||||
|                 objectPath.unshift(contextualDomainObject); | ||||
|             } | ||||
|  | ||||
|             const actions = this.row.getContextMenuActions().map(key => this.openmct.actions.getAction(key)); | ||||
|             const menuItems = this.openmct.menus.actionsToMenuItems(actions, this.objectPath, this.currentView); | ||||
|             const menuItems = this.openmct.menus.actionsToMenuItems(actions, objectPath, this.currentView); | ||||
|             if (menuItems.length) { | ||||
|                 this.openmct.menus.showMenu(event.x, event.y, menuItems); | ||||
|             } | ||||
|   | ||||
| @@ -74,7 +74,7 @@ export default { | ||||
|             return this.domainObject && (this.currentObjectPath || this.objectPath); | ||||
|         }, | ||||
|         objectFontStyle() { | ||||
|             return this.domainObject && this.domainObject.configuration && this.domainObject.configuration.fontStyle; | ||||
|             return this.domainObject?.configuration?.fontStyle; | ||||
|         }, | ||||
|         fontSize() { | ||||
|             return this.objectFontStyle ? this.objectFontStyle.fontSize : this.layoutFontSize; | ||||
| @@ -287,6 +287,8 @@ export default { | ||||
|  | ||||
|             this.$nextTick(() => { | ||||
|                 this.updateStyle(this.styleRuleManager?.currentStyle); | ||||
|                 this.setFontSize(this.fontSize); | ||||
|                 this.setFont(this.font); | ||||
|                 this.getActionCollection(); | ||||
|             }); | ||||
|         }, | ||||
| @@ -329,9 +331,9 @@ export default { | ||||
|         }, | ||||
|         initObjectStyles() { | ||||
|             if (!this.styleRuleManager) { | ||||
|                 this.styleRuleManager = new StyleRuleManager((this.domainObject.configuration && this.domainObject.configuration.objectStyles), this.openmct, this.updateStyle.bind(this), true); | ||||
|                 this.styleRuleManager = new StyleRuleManager((this.domainObject.configuration?.objectStyles), this.openmct, this.updateStyle.bind(this), true); | ||||
|             } else { | ||||
|                 this.styleRuleManager.updateObjectStyleConfig(this.domainObject.configuration && this.domainObject.configuration.objectStyles); | ||||
|                 this.styleRuleManager.updateObjectStyleConfig(this.domainObject.configuration?.objectStyles); | ||||
|             } | ||||
|  | ||||
|             if (this.stopListeningStyles) { | ||||
| @@ -343,9 +345,6 @@ export default { | ||||
|                 this.styleRuleManager.updateObjectStyleConfig(newObjectStyle); | ||||
|             }); | ||||
|  | ||||
|             this.setFontSize(this.fontSize); | ||||
|             this.setFont(this.font); | ||||
|  | ||||
|             this.stopListeningFontStyles = this.openmct.objects.observe(this.domainObject, 'configuration.fontStyle', (newFontStyle) => { | ||||
|                 this.setFontSize(newFontStyle.fontSize); | ||||
|                 this.setFont(newFontStyle.font); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user