Reorder api (#2316)

* Added 'reorder' function to composition API

* Re-implemented reordering in Elements

* Make LAD table editable

* Remove test spec focus

* Fixing bugs with event listeners

* Clean up listeners properly in Elements pool

* Fixed race condition on drag-and-drop to initiate edit

* Implement reordering in LAD tables
This commit is contained in:
Andrew Henry
2019-03-19 10:31:56 -07:00
committed by Deep Tailor
parent 23efef4469
commit 6116351dad
9 changed files with 194 additions and 53 deletions

View File

@ -21,7 +21,11 @@ define([
topicService.and.returnValue(mutationTopic);
publicAPI = {};
publicAPI.objects = jasmine.createSpyObj('ObjectAPI', [
'get'
'get',
'mutate'
]);
publicAPI.objects.eventEmitter = jasmine.createSpyObj('eventemitter', [
'on'
]);
publicAPI.objects.get.and.callFake(function (identifier) {
return Promise.resolve({identifier: identifier});
@ -52,6 +56,14 @@ define([
{
namespace: 'test',
key: 'a'
},
{
namespace: 'test',
key: 'b'
},
{
namespace: 'test',
key: 'c'
}
]
};
@ -68,12 +80,39 @@ define([
composition.on('add', listener);
return composition.load().then(function () {
expect(listener.calls.count()).toBe(1);
expect(listener.calls.count()).toBe(3);
expect(listener).toHaveBeenCalledWith({
identifier: {namespace: 'test', key: 'a'}
});
});
});
describe('supports reordering of composition', function () {
var listener;
beforeEach(function () {
listener = jasmine.createSpy('reorderListener');
composition.on('reorder', listener);
return composition.load();
});
it('', function () {
composition.reorder(1, 0);
let newComposition =
publicAPI.objects.mutate.calls.mostRecent().args[2];
expect(listener).toHaveBeenCalledWith(1, 0);
expect(newComposition[0].key).toEqual('b');
expect(newComposition[1].key).toEqual('a');
});
it('', function () {
composition.reorder(0, 2);
let newComposition =
publicAPI.objects.mutate.calls.mostRecent().args[2];
expect(listener).toHaveBeenCalledWith(0, 2);
expect(newComposition[0].key).toEqual('c');
expect(newComposition[2].key).toEqual('a');
})
});
// TODO: Implement add/removal in new default provider.
xit('synchronizes changes between instances', function () {

View File

@ -56,7 +56,8 @@ define([
this.listeners = {
add: [],
remove: [],
load: []
load: [],
reorder: []
};
this.onProviderAdd = this.onProviderAdd.bind(this);
this.onProviderRemove = this.onProviderRemove.bind(this);
@ -91,6 +92,13 @@ define([
this.onProviderRemove,
this
);
} if (event === 'reorder') {
this.provider.on(
this.domainObject,
'reorder',
this.onProviderReorder,
this
)
}
}
@ -141,6 +149,13 @@ define([
this.onProviderRemove,
this
);
} else if (event === 'reorder') {
this.provider.off(
this.domainObject,
'reorder',
this.onProviderReorder,
this
);
}
}
}
@ -209,6 +224,33 @@ define([
}
};
/**
* Reorder the domain objects in this composition.
*
* A call to [load]{@link module:openmct.CompositionCollection#load}
* must have resolved before using this method.
*
* @param {number} oldIndex
* @param {number} newIndex
* @memberof module:openmct.CompositionCollection#
* @name remove
*/
CompositionCollection.prototype.reorder = function (oldIndex, newIndex, skipMutate) {
if (!skipMutate) {
this.provider.reorder(this.domainObject, oldIndex, newIndex);
} else {
this.emit('reorder', oldIndex, newIndex);
}
};
/**
* Handle reorder from provider.
* @private
*/
CompositionCollection.prototype.onProviderReorder = function (oldIndex, newIndex) {
this.reorder(oldIndex, newIndex, true);
};
/**
* Handle adds from provider.
* @private
@ -232,12 +274,12 @@ define([
* Emit events.
* @private
*/
CompositionCollection.prototype.emit = function (event, payload) {
CompositionCollection.prototype.emit = function (event, ...payload) {
this.listeners[event].forEach(function (l) {
if (l.context) {
l.callback.call(l.context, payload);
l.callback.apply(l.context, payload);
} else {
l.callback(payload);
l.callback(...payload);
}
});
};

View File

@ -126,6 +126,7 @@ define([
objectListeners = this.listeningTo[keyString] = {
add: [],
remove: [],
reorder: [],
composition: [].slice.apply(domainObject.composition)
};
}
@ -160,7 +161,7 @@ define([
});
objectListeners[event].splice(index, 1);
if (!objectListeners.add.length && !objectListeners.remove.length) {
if (!objectListeners.add.length && !objectListeners.remove.length && !objectListeners.reorder.length) {
delete this.listeningTo[keyString];
}
};
@ -203,6 +204,30 @@ define([
// TODO: this needs to be synchronized via mutation
};
DefaultCompositionProvider.prototype.reorder = function (domainObject, oldIndex, newIndex) {
let newComposition = domainObject.composition.slice();
newComposition[newIndex] = domainObject.composition[oldIndex];
newComposition[oldIndex] = domainObject.composition[newIndex];
this.publicAPI.objects.mutate(domainObject, 'composition', newComposition);
let id = objectUtils.makeKeyString(domainObject.identifier);
var listeners = this.listeningTo[id];
if (!listeners) {
return;
}
listeners.reorder.forEach(notify);
function notify(listener) {
if (listener.context) {
listener.callback.call(listener.context, oldIndex, newIndex);
} else {
listener.callback(oldIndex, newIndex);
}
}
};
/**
* Listens on general mutation topic, using injector to fetch to avoid
* circular dependencies.