Delete items

Need to decide how to handle error cases
pull/1640/head
Nicklas Gummesson 10 years ago
parent 37fb535dae
commit fa79c43151

@ -1,5 +1,7 @@
var cdb = require('cartodb.js');
var BaseDialog = cdb.ui.common.Dialog;
/**
* Abstract view for a dialog, a kind of view that takes up the full screen overlaying any previous content.
*
@ -20,7 +22,7 @@ var cdb = require('cartodb.js');
* // To render & show initially (only to be called once):
* dialog.appendToBody();
*/
module.exports = cdb.ui.common.Dialog.extend({
module.exports = BaseDialog.extend({
className: 'Dialog',
overrideDefaults: {
@ -46,7 +48,7 @@ module.exports = cdb.ui.common.Dialog.extend({
// The timeout should match the .Dialog--closing animation duration.
var self = this;
setTimeout(function() {
cdb.ui.common.Dialog.prototype._cancel.apply(self, arguments);
BaseDialog.prototype._cancel.apply(self, arguments);
}, 80); //ms
}
});

@ -137,7 +137,11 @@ module.exports = cdb.core.View.extend({
this._scrollToTop();
},
_onDataFetched: function(coll, opts) {
/**
* Arguments may vary, depending on if it's the collection or a model that triggers the event callback.
* @private
*/
_onDataFetched: function() {
var activeViews = [ 'filters', 'content_footer' ];
var tag = this.router.model.get('tag');
var q = this.router.model.get('q');
@ -146,7 +150,7 @@ module.exports = cdb.core.View.extend({
var locked = this.router.model.get('locked');
var library = this.router.model.get('library');
if (coll.size() === 0) {
if (this.collection.size() === 0) {
if (!tag && !q && !shared && !locked && !liked) {
if (this.router.model.get('content_type') === "maps") {

@ -14,7 +14,7 @@
<button class="Button Button--secondary cancel">
<span>cancel</span>
</button>
<button class="Button Button--negative">
<button class="Button Button--negative js-ok">
<span>Ok, delete</span>
</button>
</div>

@ -1,11 +1,18 @@
var BaseDialog = require('new_common/views/base_dialog/view');
var pluralizeString = require('new_common/view_helpers/pluralize_string');
var queue = require('queue-async');
/**
* Delete items dialog
*/
module.exports = BaseDialog.extend({
events: function() {
return _.extend({}, BaseDialog.prototype.events, {
'click .js-ok' : '_deleteSelected'
});
},
initialize: function(args) {
this.elder('initialize');
this.collection = args.collection;
@ -23,5 +30,32 @@ module.exports = BaseDialog.extend({
totalCount: totalCount,
pluralizedContentType: pluralizeString(this.router.model.get('content_type') === 'datasets' ? 'dataset' : 'map', totalCount)
})
},
_deleteSelected: function(e) {
this.killEvent(e);
var q = queue(5); // # items to destroy in parallel
_.each(this.collection.where({ selected: true }), function(m) {
q.defer(function(callback) {
m.destroy({ wait: true })
.done(function() {
callback(null, arguments);
})
.fail(function() {
callback(arguments)
});
});
});
var self = this;
q.awaitAll(function(error, results) {
// error and results contains outcome of the jqXHR requests above, see http://api.jquery.com/jQuery.ajax/#jqXHR
if (error) {
// TODO: How should errors be handled?
} else {
self.hide();
}
})
}
});

@ -1,4 +1,5 @@
var DeleteItems = require('new_dashboard/dialogs/delete_items/view');
var $ = require('jquery');
var Router = require('new_dashboard/router');
describe('new_dashboard/dialogs/delete_items/view', function() {
@ -37,6 +38,52 @@ describe('new_dashboard/dialogs/delete_items/view', function() {
expect(this.html).toContain('delete 2 datasets');
expect(this.html).toContain('them'); // the object pronoun of the sentence
});
describe('and OK button is clicked', function() {
beforeEach(function() {
this.deferreds = [];
this.collection.each(function(m, i) {
this.deferreds[i] = $.Deferred();
spyOn(m, 'destroy').and.returnValue(this.deferreds[i].promise());
}, this);
spyOn(this.view, 'hide');
this.view.$('.js-ok').click();
});
it('should destroy selected items', function() {
expect(this.collection.at(0).destroy).toHaveBeenCalled();
expect(this.collection.at(2).destroy).toHaveBeenCalled();
});
it('should not remove items from collection until DELETE response comes back successfully', function() {
expect(this.collection.at(0).destroy).toHaveBeenCalledWith(jasmine.objectContaining({ wait: true }));
expect(this.collection.at(2).destroy).toHaveBeenCalledWith(jasmine.objectContaining({ wait: true }));
});
it('should NOT destroy unselected items', function() {
expect(this.collection.at(1).destroy).not.toHaveBeenCalled();
});
it('should hide dialog but not until all items deleted', function() {
// Still one pending after 1st resolve
this.deferreds[0].resolve();
expect(this.view.hide).not.toHaveBeenCalled();
// 2nd resolve, all should be done
this.deferreds[2].resolve();
expect(this.view.hide).toHaveBeenCalled();
});
it('should TBD if any item cannot be deleted', function() {
// 1st fails, so even if 2nd resolves should not hide view
// TODO: How should errors be handled?
this.deferreds[0].fail();
this.deferreds[2].resolve();
expect(this.view.hide).not.toHaveBeenCalled();
});
});
});
afterEach(function() {

@ -43,6 +43,7 @@
"load-grunt-tasks": "~0.2.0",
"moment": "^2.8.4",
"open": "0.0.5",
"queue-async": "^1.0.7",
"remapify": "^1.3.0",
"rewireify": "0.0.13",
"shelljs": "~0.2.6",

Loading…
Cancel
Save