diff options
author | Vincent Petry <pvince81@owncloud.com> | 2016-01-27 15:09:59 +0100 |
---|---|---|
committer | Vincent Petry <pvince81@owncloud.com> | 2016-01-27 15:09:59 +0100 |
commit | 714d8c2424323a449f3d4fa9ea81a76260f0014c (patch) | |
tree | 3aacddc1bcad25b46ad3ca07e3364cc040a6a7bb /core | |
parent | 308396b770f3b1b41ba31ff0ee889d485b14d14a (diff) | |
download | nextcloud-server-714d8c2424323a449f3d4fa9ea81a76260f0014c.tar.gz nextcloud-server-714d8c2424323a449f3d4fa9ea81a76260f0014c.zip |
Fix system tags conflict situations
Does not disrupt the UX whenever a tag or association was created
concurrently. The input field will adjust itself as if the tag was
already there in the first place.
Diffstat (limited to 'core')
-rw-r--r-- | core/js/systemtags/systemtagsinputfield.js | 29 | ||||
-rw-r--r-- | core/js/tests/specs/systemtags/systemtagsinputfieldSpec.js | 59 |
2 files changed, 85 insertions, 3 deletions
diff --git a/core/js/systemtags/systemtagsinputfield.js b/core/js/systemtags/systemtagsinputfield.js index b90ecbe4265..ae9f93ca671 100644 --- a/core/js/systemtags/systemtagsinputfield.js +++ b/core/js/systemtags/systemtagsinputfield.js @@ -186,6 +186,12 @@ return false; }, + _addToSelect2Selection: function(selection) { + var data = this.$tagsField.select2('data'); + data.push(selection); + this.$tagsField.select2('data', data); + }, + /** * Event handler whenever a tag is selected. * Also called whenever tag creation is requested through the dummy tag object. @@ -204,10 +210,27 @@ userAssignable: true }, { success: function(model) { - var data = self.$tagsField.select2('data'); - data.push(model.toJSON()); - self.$tagsField.select2('data', data); + self._addToSelect2Selection(model.toJSON()); self.trigger('select', model); + }, + error: function(model, xhr) { + if (xhr.status === 409) { + // re-fetch collection to get the missing tag + self.collection.reset(); + self.collection.fetch({ + success: function(collection) { + // find the tag in the collection + var model = collection.where({name: e.object.name, userVisible: true, userAssignable: true}); + if (model.length) { + model = model[0]; + // the tag already exists or was already assigned, + // add it to the list anyway + self._addToSelect2Selection(model.toJSON()); + self.trigger('select', model); + } + } + }); + } } }); this.$tagsField.select2('close'); diff --git a/core/js/tests/specs/systemtags/systemtagsinputfieldSpec.js b/core/js/tests/specs/systemtags/systemtagsinputfieldSpec.js index 07e926cd2a9..0ad383860bc 100644 --- a/core/js/tests/specs/systemtags/systemtagsinputfieldSpec.js +++ b/core/js/tests/specs/systemtags/systemtagsinputfieldSpec.js @@ -158,6 +158,65 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() { expect(selectHandler.calledOnce).toEqual(true); expect(selectHandler.getCall(0).args[0]).toEqual('2'); }); + it('triggers select event and still adds to list even in case of conflict', function() { + var selectHandler = sinon.stub(); + view.on('select', selectHandler); + var fetchStub = sinon.stub(OC.SystemTags.SystemTagsCollection.prototype, 'fetch'); + var createStub = sinon.stub(OC.SystemTags.SystemTagsCollection.prototype, 'create'); + view.$el.find('input').trigger(new $.Event('select2-selecting', { + object: { + id: -1, + name: 'newname', + isNew: true + } + })); + + expect(createStub.calledOnce).toEqual(true); + expect(createStub.getCall(0).args[0]).toEqual({ + name: 'newname', + userVisible: true, + userAssignable: true + }); + + var newModel = new OC.SystemTags.SystemTagModel({ + id: '123', + name: 'newname', + userVisible: true, + userAssignable: true + }); + + // not called yet + expect(selectHandler.notCalled).toEqual(true); + + select2Stub.withArgs('data').returns([{ + id: '1', + name: 'abc' + }]); + + // simulate conflict response for tag creation + createStub.yieldTo('error', view.collection, {status: 409}); + + // at this point it fetches from the server + expect(fetchStub.calledOnce).toEqual(true); + // simulate fetch result by adding model to the collection + view.collection.add(newModel); + fetchStub.yieldTo('success', view.collection); + + expect(select2Stub.lastCall.args[0]).toEqual('data'); + expect(select2Stub.lastCall.args[1]).toEqual([{ + id: '1', + name: 'abc' + }, + newModel.toJSON() + ]); + + // select event still called + expect(selectHandler.calledOnce).toEqual(true); + expect(selectHandler.getCall(0).args[0]).toEqual(newModel); + + createStub.restore(); + fetchStub.restore(); + }); }); describe('tag actions', function() { var opts; |