diff --git a/client/issues/issue.css b/client/issues/issue.css index 2b44398..8b69bb4 100644 --- a/client/issues/issue.css +++ b/client/issues/issue.css @@ -24,6 +24,25 @@ vertical-align: middle; } +.claimed-text { + padding-right: 50px; + color: white; + border-size: 5px; + border-radius: 5px; +} +.claim-button, .unclaim-button { + background-color: green; + border-radius: 2px; + border-size: 2px; + border-color: transparent; + float: right; + cursor: pointer; +} + +.unclaim-button { + background-color: red; +} + .needs-response { background-color: white; border-radius: 2px; diff --git a/client/issues/issue.html b/client/issues/issue.html index 9e3f7c8..d8f2591 100644 --- a/client/issues/issue.html +++ b/client/issues/issue.html @@ -6,6 +6,18 @@ #{{issueDocument.number}} ({{status}}) + {{#unless claimed}} + + {{else}} + +
+ Issue has been claimed by {{claimedBy}} +
+ {{/unless}} {{#if displayNeedsResponseButton}}
needs response diff --git a/client/issues/issue.js b/client/issues/issue.js index 2560ff1..0dd42ec 100644 --- a/client/issues/issue.js +++ b/client/issues/issue.js @@ -56,5 +56,21 @@ Template.issue.events({ number: this.issueDocument.number }); Session.set(displayId(this), false); + }, + 'click .claim-button': function() { + Meteor.call('claim', { + repoOwner: this.repoOwner, + repoName: this.repoName, + number: this.issueDocument.number + }); + Session.set(displayId(this), false); + }, + 'click .unclaim-button': function() { + Meteor.call('unclaim', { + repoOwner: this.repoOwner, + repoName: this.repoName, + number: this.issueDocument.number + }); + Session.set(displayId(this), false); } }); diff --git a/packages/hubble:issue-sync/classify.js b/packages/hubble:issue-sync/classify.js index ae41857..14afe91 100644 --- a/packages/hubble:issue-sync/classify.js +++ b/packages/hubble:issue-sync/classify.js @@ -12,6 +12,49 @@ P.asyncMethod('needsResponse', function (options, cb) { recordAction('needsResponses', options, cb); }); +Meteor.methods( +{ + claim : function(options, cb) { + check(options, { + repoOwner: String, + repoName: String, + number: Match.Integer + }); + var mongoId = P.issueMongoId(options.repoOwner, options.repoName, options.number); + if (! Issues.findOne(mongoId)) { + cb(new Meteor.Error(404, "No such issue")); + return; + } + var user = new Meteor.user(); + Issues.update(mongoId, { + $set: { + claimed: true, + claimedBy: user.services.github.username + } + }); + }, + + unclaim: function(options, cb) { + check(options, { + repoOwner: String, + repoName: String, + number: Match.Integer + }); + var mongoId = P.issueMongoId(options.repoOwner, options.repoName, options.number); + if (! Issues.findOne(mongoId)) { + cb(new Meteor.Error(404, "No such issue")); + return; + } + var user = new Meteor.user(); + Issues.update(mongoId, { + $set: { + claimed: false, + claimedBy: null + } + }); + } +}); + var recordAction = function (actionField, options, cb) { var mongoId; diff --git a/publish.js b/publish.js index 790e240..582263e 100644 --- a/publish.js +++ b/publish.js @@ -15,7 +15,9 @@ if (Meteor.isServer) { lastUpdateOrComment: 1, highlyActive: 1, status: 1, - canBeSnoozed: 1 + canBeSnoozed: 1, + claimed: 1, + claimedBy: 1 }; Meteor.publish('issues-by-status', function (status) {