Skip to content

Commit

Permalink
allow bulk delete of ticks
Browse files Browse the repository at this point in the history
  • Loading branch information
sanderpick committed May 17, 2015
1 parent 033bddf commit bc2bdd5
Show file tree
Hide file tree
Showing 11 changed files with 98 additions and 65 deletions.
3 changes: 3 additions & 0 deletions lib/resources/ascent.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ exports.routes = function () {
// Get the ascent.
db.Ascents.read({_id: id}, function (err, doc) {
if (err) return cb(err);
if (!doc) {
return cb({error: {code: 404, message: 'Ascent not found'}});
}
if (member._id.toString() !== doc.author_id.toString() && !member.admin) {
return cb({error: {code: 403, message: 'Member invalid'}});
}
Expand Down
2 changes: 1 addition & 1 deletion lib/resources/crag.js
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,7 @@ exports.routes = function () {

// Get the crag
db.Crags.read({key: key}, function (err, doc) {
if (errorHandler(err, req, res)) return;
if (errorHandler(err, req, res, doc, 'crag')) return;
if ((!doc.author_id || mid.toString() !== doc.author_id.toString()) &&
!req.user.admin) {
return res.send(403, {error: {message: 'Member invalid'}});
Expand Down
132 changes: 82 additions & 50 deletions lib/resources/tick.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,53 +50,26 @@ exports.routes = function () {
var errorHandler = app.get('errorHandler');
var events = app.get('events');

// List
app.post('/api/ticks/list', function (req, res) {
var cursor = req.body.cursor || 0;
var limit = req.body.limit || 5;
var query = {};

if (req.body.author_id) {
query.author_id = db.oid(req.body.author_id);
}
if (req.body.parent_id) {
query.parent_id = db.oid(req.body.parent_id);
function deleteTick(id, member, cb) {
if (!member) {
return cb({code: 403, error: {message: 'Member invalid'}});
}

db.Ticks.list(query, {sort: {created: 1}, limit: limit,
skip: limit * cursor, inflate: {author: profiles.member}},
function (err, ticks) {
if (errorHandler(err, req, res)) return;

// Send profile.
res.send(iutil.client({
ticks: {
cursor: ++cursor,
more: ticks && ticks.length === limit,
items: ticks
}
}));

});

});

// Delete
app.delete('/api/ticks/:id', function (req, res) {
if (!req.user) {
return res.send(403, {error: 'Member invalid'});
if (_.isString(id)) {
id = db.oid(id);
}

// Get the tick.
db.Ticks.read({_id: db.oid(req.params.id)}, function (err, doc) {
if (errorHandler(err, req, res, doc, 'tick')) return;
if (req.user._id.toString() !== doc.author_id.toString()) {
return res.send(403, {error: 'Member invalid'});
db.Ticks.read({_id: id}, function (err, doc) {
if (err) return cb(err);
if (!doc) {
return cb({error: {code: 404, message: 'Tick not found'}});
}
if (member._id.toString() !== doc.author_id.toString()) {
return cb({error: {code: 403, message: 'Member invalid'}});
}

// Get the event (from creation).
db.Events.read({action_id: doc._id}, function (err, event) {
if (errorHandler(err, req, res)) return;
if (err) return cb(err);

Step(
function () {
Expand Down Expand Up @@ -132,43 +105,102 @@ exports.routes = function () {
db.Comments.remove({parent_id: doc._id}, this.parallel());
db.Hangtens.remove({parent_id: doc._id}, this.parallel());
db.Subscriptions.remove({subscribee_id: doc._id}, this.parallel());
db.Events.remove({$or: [{target_id: doc._id}, {action_id: doc._id}]},
this.parallel());
db.Events.remove({$or: [{target_id: doc._id},
{action_id: doc._id}]}, this.parallel());

// Finally, remove the tick.
db.Ticks.remove({_id: doc._id}, this.parallel());
},
function (err) {
if (errorHandler(err, req, res)) return;
if (err) return this(err);

// Get the tick's session's other ticks.
db.Ticks.list({session_id: doc.session_id}, this);
},
function (err, ticks) {
if (errorHandler(err, req, res)) return;
if (err) return this(err);

// Remove the session if it's empty.
if (ticks.length === 0) {
Sessions.deleteSession(doc.session_id, req.user, this);
Sessions.deleteSession(doc.session_id, member, this);
} else {
this();
}
},
function (err) {
if (errorHandler(err, req, res)) return;
if (err) return cb(err);

// Publish removed status.
if (event) {
events.publish('event', 'event.removed', {data: event});
}
events.publish('tick', 'tick.removed', {data: {id: doc._id.toString()}});
events.publish('tick', 'tick.removed', {data: {id:
doc._id.toString()}});

// Finish.
res.send({removed: true});
cb();
}
);
});
});
}

// List
app.post('/api/ticks/list', function (req, res) {
var cursor = req.body.cursor || 0;
var limit = req.body.limit || 5;
var query = {};

if (req.body.author_id) {
query.author_id = db.oid(req.body.author_id);
}
if (req.body.parent_id) {
query.parent_id = db.oid(req.body.parent_id);
}

db.Ticks.list(query, {sort: {created: 1}, limit: limit,
skip: limit * cursor, inflate: {author: profiles.member}},
function (err, ticks) {
if (errorHandler(err, req, res)) return;

// Send profile.
res.send(iutil.client({
ticks: {
cursor: ++cursor,
more: ticks && ticks.length === limit,
items: ticks
}
}));

});

});

// Delete
app.delete('/api/ticks/:id', function (req, res) {
if (!req.user) {
return res.send(403, {error: 'Member invalid'});
}

if (req.params.id !== 'all') {
deleteTick(req.params.id, req.user, function (err) {
if (errorHandler(err, req, res)) return;
res.send({removed: true});
});
} else {
db.Ticks.list({author_id: req.user._id}, function (err, docs) {
if (errorHandler(err, req, res)) return;
if (docs.length === 0) {
return res.send({removed: true});
}

var done = _.after(docs.length, function (err) {
if (errorHandler(err, req, res)) return;
res.send({removedAll: true});
});
_.each(docs, function (doc) {
deleteTick(doc._id, req.user, done);
});
});
}
});

// Download
Expand Down
4 changes: 2 additions & 2 deletions public/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -5098,12 +5098,12 @@ input.import-input {
width: 480px;
margin-right: 10px;
font-size: 16px;
vertical-align: -1px;
}
.import button.button.import-search-button {
position: relative;
width: 190px;
line-height: 32px;
height: 34px;
height: 36px;
}
.import ul.list {
font-size: 14px;
Expand Down
5 changes: 3 additions & 2 deletions public/css/style.styl
Original file line number Diff line number Diff line change
Expand Up @@ -5181,12 +5181,13 @@ input.import-input
width 480px
margin-right 10px
font-size 16px
vertical-align -1px

.import button.button.import-search-button
position relative
width 190px
line-height 32px
height 34px
// line-height 36px
height 36px

.import ul.list
font-size 14px
Expand Down
2 changes: 1 addition & 1 deletion public/js/models/card.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ define([
}
ticks[grade].push(t);
} else {
var k = 'not graded by you';
var k = 'ungraded';
if (!ticks[k]) {
ticks[k] = [];
}
Expand Down
2 changes: 1 addition & 1 deletion public/js/views/lists/ascents.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ define([
// Handle type changes.
this.data.ascents.bcnt = this.data.ascents.bcnt || 0;
this.data.ascents.rcnt = this.data.ascents.rcnt || 0;
if (this.data.ascents.bcnt > this.data.ascents.rcnt) {
if (this.data.ascents.bcnt >= this.data.ascents.rcnt) {
this.currentType = 'b';
this.bouldersFilter.addClass('active');
this.boulders.show();
Expand Down
7 changes: 2 additions & 5 deletions public/js/views/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,6 @@ define([
clearAscents: function (e) {
e.preventDefault();

// Render the confirm modal.
$.fancybox(_.template(confirm)({
message: 'Clear all of your logs (work and "My Ascents") forever?',
}), {
Expand All @@ -791,15 +790,13 @@ define([
padding: 0
});

// Setup actions.
$('.modal-cancel').click(function (e) {
$.fancybox.close();
});
$('.modal-confirm').click(_.bind(function (e) {

// Delete the member.
rest.delete('/api/ascents/' + this.app.profile.member.username +
'/all', {}, _.bind(function (err, data) {
// Delete all ticks.
rest.delete('/api/ticks/all', {}, _.bind(function (err, data) {
if (err) {
mps.publish('flash/new', [{err: err, level: 'error', type: 'popup'}]);
return;
Expand Down
2 changes: 1 addition & 1 deletion public/js/views/ticks.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ define([
data.type + '">');
var grade;
if (isNaN(Number(data.grade))) {
grade = 'not graded by you';
grade = 'ungraded';
} else {
grade = this.app.gradeConverter[data.type].indexes(data.grade);
}
Expand Down
2 changes: 1 addition & 1 deletion public/templates/import.insert.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<%
var data = this.model.attributes;
var grades = ['not graded by you'].concat(this.model.grades);
var grades = ['ungraded'].concat(this.model.grades);
%>

<div class="rightside">
Expand Down
2 changes: 1 addition & 1 deletion public/templates/ticks.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

// Save model attributes
var data = this.model.attributes;
var grades = ['not graded by you'].concat(this.model.grades);
var grades = ['ungraded'].concat(this.model.grades);

var own = !this.model || (this.app.profile.member && data.author.id === this.app.profile.member.id);
var owner = own ? 'You\'re': data.author.displayName.trim() + ' is ';
Expand Down

0 comments on commit bc2bdd5

Please sign in to comment.