Prevent self-composition in layouts (#2287)

This commit is contained in:
Andrew Henry
2019-02-13 11:42:43 -08:00
committed by Deep Tailor
parent a1aa99837b
commit 21e08709cb
3 changed files with 33 additions and 3 deletions

View File

@ -215,6 +215,19 @@ define([
return utils.makeKeyString(identifier);
};
/**
* Given any number of identifiers, will return true if they are all equal, otherwise false.
* @param {module:openmct.ObjectAPI~Identifier[]} identifiers
*/
ObjectAPI.prototype.areIdsEqual = function (...identifiers) {
return identifiers.map(utils.parseKeyString)
.every(identifier => {
return identifier === identifiers[0] ||
(identifier.namespace === identifiers[0].namespace &&
identifier.key === identifiers[0].key);
});
}
/**
* Uniquely identifies a domain object.
*

View File

@ -124,6 +124,8 @@
bottom: Number.NEGATIVE_INFINITY
};
const DRAG_OBJECT_TRANSFER_PREFIX = 'openmct/domain-object/';
function getItemDefinition(itemType, ...options) {
let itemView = ITEM_TYPE_VIEW_MAP[itemType];
@ -246,7 +248,7 @@
} else {
let identifier = this.openmct.objects.makeKeyString(domainObject.identifier);
if (!this.objectViewMap[identifier]) {
if (!this.containsObject(identifier)) {
this.addItem('subobject-view', domainObject, droppedObjectPosition);
} else {
let prompt = this.openmct.overlays.dialog({
@ -264,8 +266,21 @@
}
}
},
handleDragOver($event){
containsObject(identifier) {
return _.get(this.internalDomainObject, 'composition')
.some(childId => this.openmct.objects.areIdsEqual(childId, identifier));
},
handleDragOver($event) {
// Get the ID of the dragged object
let draggedKeyString = $event.dataTransfer.types
.filter(type => type.startsWith(DRAG_OBJECT_TRANSFER_PREFIX))
.map(type => type.substring(DRAG_OBJECT_TRANSFER_PREFIX.length))[0];
// If the layout already contains the given object, then shortcut the default dragover behavior and
// potentially allow drop. Display layouts allow drag drop of duplicate telemetry objects.
if (this.containsObject(draggedKeyString)){
$event.preventDefault();
}
},
isTelemetry(domainObject) {
if (this.openmct.telemetry.isTelemetryObject(domainObject)

View File

@ -66,6 +66,7 @@ export default {
dragStart(event) {
let navigatedObject = this.openmct.router.path[0];
let serializedPath = JSON.stringify(this.objectPath);
let keyString = this.openmct.objects.makeKeyString(this.domainObject.identifier);
/*
* Cannot inspect data transfer objects on dragover/dragenter so impossible to determine composability at
@ -78,6 +79,7 @@ export default {
// serialize domain object anyway, because some views can drag-and-drop objects without composition
// (eg. notabook.)
event.dataTransfer.setData("openmct/domain-object-path", serializedPath);
event.dataTransfer.setData(`openmct/domain-object/${keyString}`, this.domainObject);
}
}
}