Explorar o código

Merge pull request #3006 from NicoP-S/master

Public vote
Lauri Ojansivu %!s(int64=5) %!d(string=hai) anos
pai
achega
a81921382a

+ 29 - 6
client/components/cards/cardDetails.jade

@@ -206,12 +206,12 @@ template(name="cardDetails")
           i.fa.fa-thumbs-up
           card-details-item-title {{_ 'vote-question'}}
         .vote-result
-          .card-label.card-label-green
-            +viewer
-              = voteCountPositive
-          .card-label.card-label-red
-            +viewer
-              = voteCountNegative
+          if votePublic
+            a.card-label.card-label-green.js-show-positive-votes {{ voteCountPositive }}
+            a.card-label.card-label-red.js-show-negative-votes {{ voteCountNegative }}
+          else
+            .card-label.card-label-green {{ voteCountPositive }}
+            .card-label.card-label-red {{ voteCountNegative }}
       +viewer
         = getVoteQuestion
       button.card-details-green.js-vote.js-vote-positive(class="{{#if voteState}}voted{{/if}}") {{_ 'vote-for-it'}}
@@ -572,6 +572,29 @@ template(name="cardStartVotingPopup")
     .fields
       label(for="vote") {{_ 'vote-question'}}
       input.js-vote-field#vote(type="text" name="vote" value="{{card.getVoteQuestion}}" autofocus)
+      label(for="vote-public") {{_ 'vote-public'}}
+        a.js-toggle-vote-public
+          .materialCheckBox#vote-public(name="vote-public")
 
     button.primary.confirm.js-submit {{_ 'save'}}
     //- button.js-remove-color.negate.wide.right {{_ 'delete'}}
+
+template(name="positiveVoteMembersPopup")
+  ul.pop-over-list.js-card-member-list
+    each m in voteMemberPositive
+      li.item
+        a.name
+          +userAvatar(userId=m._id)
+          span.full-name
+            = m.profile.fullname
+            | (<span class="username">{{ m.username }}</span>)
+
+template(name="negativeVoteMembersPopup")
+  ul.pop-over-list.js-card-member-list
+    each m in voteMemberNegative
+      li.item
+        a.name
+          +userAvatar(userId=m._id)
+          span.full-name
+            = m.profile.fullname
+            | (<span class="username">{{ m.username }}</span>)

+ 19 - 6
client/components/cards/cardDetails.js

@@ -54,6 +54,12 @@ BlazeComponent.extendComponent({
     }
     return null;
   },
+  votePublic() {
+    const card = this.currentData();
+    if (card.vote)
+      return card.vote.public
+    return null
+  },
   voteCountPositive() {
     const card = this.currentData();
     if (card.vote && card.vote.positive) return card.vote.positive.length;
@@ -382,6 +388,8 @@ BlazeComponent.extendComponent({
         'click .js-start-date': Popup.open('editCardStartDate'),
         'click .js-due-date': Popup.open('editCardDueDate'),
         'click .js-end-date': Popup.open('editCardEndDate'),
+        'click .js-show-positive-votes':Popup.open('positiveVoteMembers'),
+        'click .js-show-negative-votes': Popup.open('negativeVoteMembers'),
         'mouseenter .js-card-details'() {
           const parentComponent = this.parentComponent().parentComponent();
           //on mobile view parent is Board, not BoardBody.
@@ -647,7 +655,7 @@ Template.cardDetailsActionsPopup.events({
   },
 });
 
-Template.editCardTitleForm.onRendered(function() {
+Template.editCardTitleForm.onRendered(function () {
   autosize(this.$('.js-edit-card-title'));
 });
 
@@ -661,7 +669,7 @@ Template.editCardTitleForm.events({
   },
 });
 
-Template.editCardRequesterForm.onRendered(function() {
+Template.editCardRequesterForm.onRendered(function () {
   autosize(this.$('.js-edit-card-requester'));
 });
 
@@ -674,7 +682,7 @@ Template.editCardRequesterForm.events({
   },
 });
 
-Template.editCardAssignerForm.onRendered(function() {
+Template.editCardAssignerForm.onRendered(function () {
   autosize(this.$('.js-edit-card-assigner'));
 });
 
@@ -814,7 +822,7 @@ Template.copyChecklistToManyCardsPopup.events({
 
         // copy subtasks
         cursor = Cards.find({ parentId: oldId });
-        cursor.forEach(function() {
+        cursor.forEach(function () {
           'use strict';
           const subtask = arguments[0];
           subtask.parentId = _id;
@@ -963,7 +971,7 @@ BlazeComponent.extendComponent({
             }
           }
         },
-        'click .js-delete': Popup.afterConfirm('cardDelete', function() {
+        'click .js-delete': Popup.afterConfirm('cardDelete', function () {
           Popup.close();
           Cards.remove(this._id);
           Utils.goBoardId(this.boardId);
@@ -1001,9 +1009,14 @@ BlazeComponent.extendComponent({
         'submit .edit-vote-question'(evt) {
           evt.preventDefault();
           const voteQuestion = evt.target.vote.value;
-          this.currentCard.setVoteQuestion(voteQuestion);
+          const publicVote = $('#vote-public').hasClass('is-checked');
+          this.currentCard.setVoteQuestion(voteQuestion, publicVote);
           Popup.close();
         },
+        'click a.js-toggle-vote-public'(event) {
+          event.preventDefault();
+          $('#vote-public').toggleClass('is-checked');
+        },
       },
     ];
   },

+ 2 - 0
client/components/cards/cardDetails.styl

@@ -338,3 +338,5 @@ card-details-color(background, color...)
   justify-content: space-between
 .vote-result
   display: flex
+.js-show-positive-votes
+  cursor: pointer

+ 3 - 0
i18n/en.i18n.json

@@ -164,7 +164,10 @@
   "cardCustomField-datePopup-title": "Change date",
   "cardCustomFieldsPopup-title": "Edit custom fields",
   "cardStartVotingPopup-title": "Start a vote",
+  "positiveVoteMembersPopup-title": "Proponents",
+  "negativeVoteMembersPopup-title": "Opponents",
   "vote-question": "Voting question",
+  "vote-public": "Public vote",
   "vote-for-it": "for it",
   "vote-against": "against",
   "cardDeletePopup-title": "Delete Card?",

+ 44 - 12
models/cards.js

@@ -336,6 +336,10 @@ Cards.attachSchema(
       optional: true,
       defaultValue: null,
     },
+    'vote.public': {
+      type: Boolean,
+      defaultValue: false,
+    },
   }),
 );
 
@@ -728,7 +732,7 @@ Cards.helpers({
 
   parentString(sep) {
     return this.parentList()
-      .map(function(elem) {
+      .map(function (elem) {
         return elem.title;
       })
       .join(sep);
@@ -1028,6 +1032,33 @@ Cards.helpers({
     }
   },
 
+  getVotePublic() {
+    if (this.isLinkedCard()) {
+      const card = Cards.findOne({ _id: this.linkedId });
+      if (card && card.vote) return card.vote.public;
+      else return null;
+    } else if (this.isLinkedBoard()) {
+      const board = Boards.findOne({ _id: this.linkedId });
+      if (board && board.vote) return board.vote.public;
+      else return null;
+    } else if (this.vote) {
+      return this.vote.public;
+    } else {
+      return null;
+    }
+  },
+
+  voteMemberPositive() {
+    if (this.vote && this.vote.positive)
+      return Users.find({ _id: { $in: this.vote.positive } })
+    return []
+  },
+  voteMemberNegative() {
+    if (this.vote && this.vote.negative)
+      return Users.find({ _id: { $in: this.vote.negative } })
+    return []
+  },
+
   getId() {
     if (this.isLinked()) {
       return this.linkedId;
@@ -1444,11 +1475,12 @@ Cards.mutations({
       },
     };
   },
-  setVoteQuestion(question) {
+  setVoteQuestion(question, public) {
     return {
       $set: {
         vote: {
           question,
+          public,
           positive: [],
           negative: [],
         },
@@ -1897,7 +1929,7 @@ if (Meteor.isServer) {
   });
 
   //New activity for card moves
-  Cards.after.update(function(userId, doc, fieldNames) {
+  Cards.after.update(function (userId, doc, fieldNames) {
     const oldListId = this.previous.listId;
     const oldSwimlaneId = this.previous.swimlaneId;
     const oldBoardId = this.previous.boardId;
@@ -1943,7 +1975,7 @@ if (Meteor.isServer) {
         // change list modifiedAt, when user modified the key values in timingaction array, if it's endAt, put the modifiedAt of list back to one year ago for sorting purpose
         const modifiedAt = new Date(
           new Date(value).getTime() -
-            (action === 'endAt' ? 365 * 24 * 3600 * 1e3 : 0),
+          (action === 'endAt' ? 365 * 24 * 3600 * 1e3 : 0),
         ); // set it as 1 year before
         const boardId = list.boardId;
         Lists.direct.update(
@@ -1997,7 +2029,7 @@ if (Meteor.isServer) {
   JsonRoutes.add(
     'GET',
     '/api/boards/:boardId/swimlanes/:swimlaneId/cards',
-    function(req, res) {
+    function (req, res) {
       const paramBoardId = req.params.boardId;
       const paramSwimlaneId = req.params.swimlaneId;
       Authentication.checkBoardAccess(req.userId, paramBoardId);
@@ -2007,7 +2039,7 @@ if (Meteor.isServer) {
           boardId: paramBoardId,
           swimlaneId: paramSwimlaneId,
           archived: false,
-        }).map(function(doc) {
+        }).map(function (doc) {
           return {
             _id: doc._id,
             title: doc.title,
@@ -2031,7 +2063,7 @@ if (Meteor.isServer) {
    *                title: string,
    *                description: string}]
    */
-  JsonRoutes.add('GET', '/api/boards/:boardId/lists/:listId/cards', function(
+  JsonRoutes.add('GET', '/api/boards/:boardId/lists/:listId/cards', function (
     req,
     res,
   ) {
@@ -2044,7 +2076,7 @@ if (Meteor.isServer) {
         boardId: paramBoardId,
         listId: paramListId,
         archived: false,
-      }).map(function(doc) {
+      }).map(function (doc) {
         return {
           _id: doc._id,
           title: doc.title,
@@ -2066,7 +2098,7 @@ if (Meteor.isServer) {
   JsonRoutes.add(
     'GET',
     '/api/boards/:boardId/lists/:listId/cards/:cardId',
-    function(req, res) {
+    function (req, res) {
       const paramBoardId = req.params.boardId;
       const paramListId = req.params.listId;
       const paramCardId = req.params.cardId;
@@ -2098,7 +2130,7 @@ if (Meteor.isServer) {
    * @param {string} [assignees] the array of maximum one ID of assignee of the new card
    * @return_type {_id: string}
    */
-  JsonRoutes.add('POST', '/api/boards/:boardId/lists/:listId/cards', function(
+  JsonRoutes.add('POST', '/api/boards/:boardId/lists/:listId/cards', function (
     req,
     res,
   ) {
@@ -2205,7 +2237,7 @@ if (Meteor.isServer) {
   JsonRoutes.add(
     'PUT',
     '/api/boards/:boardId/lists/:listId/cards/:cardId',
-    function(req, res) {
+    function (req, res) {
       Authentication.checkUserId(req.userId);
       const paramBoardId = req.params.boardId;
       const paramCardId = req.params.cardId;
@@ -2504,7 +2536,7 @@ if (Meteor.isServer) {
   JsonRoutes.add(
     'DELETE',
     '/api/boards/:boardId/lists/:listId/cards/:cardId',
-    function(req, res) {
+    function (req, res) {
       Authentication.checkUserId(req.userId);
       const paramBoardId = req.params.boardId;
       const paramListId = req.params.listId;

+ 1 - 0
models/trelloCreator.js

@@ -303,6 +303,7 @@ export class TrelloCreator {
         if (positiveVotes.length > 0) {
           cardToCreate.vote = {
             question: cardToCreate.title,
+            public: true,
             positive: positiveVotes,
           }
         }