瀏覽代碼

Assignee field. In Progress.

Thanks to xet7 !

Related #2452
Lauri Ojansivu 5 年之前
父節點
當前提交
306301e881
共有 2 個文件被更改,包括 164 次插入1 次删除
  1. 2 1
      client/lib/filter.js
  2. 162 0
      models/cards.js

+ 2 - 1
client/lib/filter.js

@@ -451,10 +451,11 @@ Filter = {
   // before changing the schema.
   // before changing the schema.
   labelIds: new SetFilter(),
   labelIds: new SetFilter(),
   members: new SetFilter(),
   members: new SetFilter(),
+  assignees: new SetFilter(),
   customFields: new SetFilter('_id'),
   customFields: new SetFilter('_id'),
   advanced: new AdvancedFilter(),
   advanced: new AdvancedFilter(),
 
 
-  _fields: ['labelIds', 'members', 'customFields'],
+  _fields: ['labelIds', 'members', 'assignees', 'customFields'],
 
 
   // We don't filter cards that have been added after the last filter change. To
   // We don't filter cards that have been added after the last filter change. To
   // implement this we keep the id of these cards in this `_exceptions` fields
   // implement this we keep the id of these cards in this `_exceptions` fields

+ 162 - 0
models/cards.js

@@ -201,6 +201,14 @@ Cards.attachSchema(
       optional: true,
       optional: true,
       defaultValue: [],
       defaultValue: [],
     },
     },
+    assignees: {
+      /**
+       * list of assignees (user IDs) who are responsible for completing card
+       */
+      type: [String],
+      optional: true,
+      defaultValue: [],
+    },
     receivedAt: {
     receivedAt: {
       /**
       /**
        * Date the card was received
        * Date the card was received
@@ -409,6 +417,10 @@ Cards.helpers({
     return _.contains(this.getMembers(), memberId);
     return _.contains(this.getMembers(), memberId);
   },
   },
 
 
+  isAssignee(assigneeId) {
+    return _.contains(this.getAssignee(), assigneeId);
+  },
+
   activities() {
   activities() {
     if (this.isLinkedCard()) {
     if (this.isLinkedCard()) {
       return Activities.find(
       return Activities.find(
@@ -743,6 +755,20 @@ Cards.helpers({
     }
     }
   },
   },
 
 
+  getAssignees() {
+    if (this.isLinkedCard()) {
+      const card = Cards.findOne({ _id: this.linkedId });
+      return card.assignees;
+    } else if (this.isLinkedBoard()) {
+      const board = Boards.findOne({ _id: this.linkedId });
+      return board.activeAssignees().map(assignee => {
+        return assignee.userId;
+      });
+    } else {
+      return this.assignees;
+    }
+  },
+
   assignMember(memberId) {
   assignMember(memberId) {
     if (this.isLinkedCard()) {
     if (this.isLinkedCard()) {
       return Cards.update(
       return Cards.update(
@@ -760,6 +786,23 @@ Cards.helpers({
     }
     }
   },
   },
 
 
+  assignAssignee(assigneeId) {
+    if (this.isLinkedCard()) {
+      return Cards.update(
+        { _id: this.linkedId },
+        { $addToSet: { assignees: assigneeId } },
+      );
+    } else if (this.isLinkedBoard()) {
+      const board = Boards.findOne({ _id: this.linkedId });
+      return board.addAssignee(assigneeId);
+    } else {
+      return Cards.update(
+        { _id: this._id },
+        { $addToSet: { assignees: assigneeId } },
+      );
+    }
+  },
+
   unassignMember(memberId) {
   unassignMember(memberId) {
     if (this.isLinkedCard()) {
     if (this.isLinkedCard()) {
       return Cards.update(
       return Cards.update(
@@ -774,6 +817,23 @@ Cards.helpers({
     }
     }
   },
   },
 
 
+  unassignAssignee(assigneeId) {
+    if (this.isLinkedCard()) {
+      return Cards.update(
+        { _id: this.linkedId },
+        { $pull: { assignees: assigneeId } },
+      );
+    } else if (this.isLinkedBoard()) {
+      const board = Boards.findOne({ _id: this.linkedId });
+      return board.removeAssignee(assigneeId);
+    } else {
+      return Cards.update(
+        { _id: this._id },
+        { $pull: { assignees: assigneeId } },
+      );
+    }
+  },
+
   toggleMember(memberId) {
   toggleMember(memberId) {
     if (this.getMembers() && this.getMembers().indexOf(memberId) > -1) {
     if (this.getMembers() && this.getMembers().indexOf(memberId) > -1) {
       return this.unassignMember(memberId);
       return this.unassignMember(memberId);
@@ -782,6 +842,14 @@ Cards.helpers({
     }
     }
   },
   },
 
 
+  toggleAssignee(assigneeId) {
+    if (this.getAssignees() && this.getAssignees().indexOf(assigneeId) > -1) {
+      return this.unassignAssignee(assigneeId);
+    } else {
+      return this.assignAssignee(assigneeId);
+    }
+  },
+
   getReceived() {
   getReceived() {
     if (this.isLinkedCard()) {
     if (this.isLinkedCard()) {
       const card = Cards.findOne({ _id: this.linkedId });
       const card = Cards.findOne({ _id: this.linkedId });
@@ -1124,6 +1192,14 @@ Cards.mutations({
     };
     };
   },
   },
 
 
+  assignAssignee(assigneeId) {
+    return {
+      $addToSet: {
+        assignees: assigneeId,
+      },
+    };
+  },
+
   unassignMember(memberId) {
   unassignMember(memberId) {
     return {
     return {
       $pull: {
       $pull: {
@@ -1132,6 +1208,14 @@ Cards.mutations({
     };
     };
   },
   },
 
 
+  unassignAssignee(assigneeId) {
+    return {
+      $pull: {
+        assignee: assigneeId,
+      },
+    };
+  },
+
   toggleMember(memberId) {
   toggleMember(memberId) {
     if (this.members && this.members.indexOf(memberId) > -1) {
     if (this.members && this.members.indexOf(memberId) > -1) {
       return this.unassignMember(memberId);
       return this.unassignMember(memberId);
@@ -1140,6 +1224,14 @@ Cards.mutations({
     }
     }
   },
   },
 
 
+  toggleAssignee(assigneeId) {
+    if (this.assignees && this.assignees.indexOf(assigneeId) > -1) {
+      return this.unassignAssignee(assigneeId);
+    } else {
+      return this.assignAssignee(assigneeId);
+    }
+  },
+
   assignCustomField(customFieldId) {
   assignCustomField(customFieldId) {
     return {
     return {
       $addToSet: {
       $addToSet: {
@@ -1414,6 +1506,28 @@ function cardMembers(userId, doc, fieldNames, modifier) {
     }
     }
   }
   }
 
 
+  function cardAssignees(userId, doc, fieldNames, modifier) {
+    if (!_.contains(fieldNames, 'assignees')) return;
+    let assigneeId;
+    // Say hello to the new assignee
+    if (modifier.$addToSet && modifier.$addToSet.assignees) {
+      assigneeId = modifier.$addToSet.assignees;
+      const username = Users.findOne(assigneeId).username;
+      if (!_.contains(doc.assignees, assigneeId)) {
+        Activities.insert({
+          userId,
+          username,
+          activityType: 'joinAssignee',
+          boardId: doc.boardId,
+          cardId: doc._id,
+          assigneeId,
+          listId: doc.listId,
+          swimlaneId: doc.swimlaneId,
+        });
+      }
+    }
+  }
+
   // Say goodbye to the former member
   // Say goodbye to the former member
   if (modifier.$pull && modifier.$pull.members) {
   if (modifier.$pull && modifier.$pull.members) {
     memberId = modifier.$pull.members;
     memberId = modifier.$pull.members;
@@ -1432,6 +1546,25 @@ function cardMembers(userId, doc, fieldNames, modifier) {
       });
       });
     }
     }
   }
   }
+
+  // Say goodbye to the former assignee
+  if (modifier.$pull && modifier.$pull.assignees) {
+    assigneeId = modifier.$pull.assignees;
+    const username = Users.findOne(assigneeId).username;
+    // Check that the former assignee is assignee of the card
+    if (_.contains(doc.assignees, assigneeId)) {
+      Activities.insert({
+        userId,
+        username,
+        activityType: 'unjoinAssignee',
+        boardId: doc.boardId,
+        cardId: doc._id,
+        assigneeId,
+        listId: doc.listId,
+        swimlaneId: doc.swimlaneId,
+      });
+    }
+  }
 }
 }
 
 
 function cardLabels(userId, doc, fieldNames, modifier) {
 function cardLabels(userId, doc, fieldNames, modifier) {
@@ -1650,6 +1783,12 @@ if (Meteor.isServer) {
     updateActivities(doc, fieldNames, modifier);
     updateActivities(doc, fieldNames, modifier);
   });
   });
 
 
+  // Add a new activity if we add or remove a assignee to the card
+  Cards.before.update((userId, doc, fieldNames, modifier) => {
+    cardAssignees(userId, doc, fieldNames, modifier);
+    updateActivities(doc, fieldNames, modifier);
+  });
+
   // Add a new activity if we add or remove a label to the card
   // Add a new activity if we add or remove a label to the card
   Cards.before.update((userId, doc, fieldNames, modifier) => {
   Cards.before.update((userId, doc, fieldNames, modifier) => {
     cardLabels(userId, doc, fieldNames, modifier);
     cardLabels(userId, doc, fieldNames, modifier);
@@ -1809,6 +1948,7 @@ if (Meteor.isServer) {
    * @param {string} description the description of the new card
    * @param {string} description the description of the new card
    * @param {string} swimlaneId the swimlane ID of the new card
    * @param {string} swimlaneId the swimlane ID of the new card
    * @param {string} [members] the member IDs list of the new card
    * @param {string} [members] the member IDs list of the new card
+   * @param {string} [assignees] the assignee IDs list of the new card
    * @return_type {_id: string}
    * @return_type {_id: string}
    */
    */
   JsonRoutes.add('POST', '/api/boards/:boardId/lists/:listId/cards', function(
   JsonRoutes.add('POST', '/api/boards/:boardId/lists/:listId/cards', function(
@@ -1830,6 +1970,7 @@ if (Meteor.isServer) {
       _id: req.body.authorId,
       _id: req.body.authorId,
     });
     });
     const members = req.body.members || [req.body.authorId];
     const members = req.body.members || [req.body.authorId];
+    const assignees = req.body.assignees;
     if (typeof check !== 'undefined') {
     if (typeof check !== 'undefined') {
       const id = Cards.direct.insert({
       const id = Cards.direct.insert({
         title: req.body.title,
         title: req.body.title,
@@ -1841,6 +1982,7 @@ if (Meteor.isServer) {
         swimlaneId: req.body.swimlaneId,
         swimlaneId: req.body.swimlaneId,
         sort: currentCards.count(),
         sort: currentCards.count(),
         members,
         members,
+        assignees,
       });
       });
       JsonRoutes.sendResult(res, {
       JsonRoutes.sendResult(res, {
         code: 200,
         code: 200,
@@ -1892,6 +2034,7 @@ if (Meteor.isServer) {
    * @param {string} [labelIds] the new list of label IDs attached to the card
    * @param {string} [labelIds] the new list of label IDs attached to the card
    * @param {string} [swimlaneId] the new swimlane ID of the card
    * @param {string} [swimlaneId] the new swimlane ID of the card
    * @param {string} [members] the new list of member IDs attached to the card
    * @param {string} [members] the new list of member IDs attached to the card
+   * @param {string} [assignees] the new list of assignee IDs attached to the card
    * @param {string} [requestedBy] the new requestedBy field of the card
    * @param {string} [requestedBy] the new requestedBy field of the card
    * @param {string} [assignedBy] the new assignedBy field of the card
    * @param {string} [assignedBy] the new assignedBy field of the card
    * @param {string} [receivedAt] the new receivedAt field of the card
    * @param {string} [receivedAt] the new receivedAt field of the card
@@ -2152,6 +2295,25 @@ if (Meteor.isServer) {
           { $set: { members: newmembers } },
           { $set: { members: newmembers } },
         );
         );
       }
       }
+      if (req.body.hasOwnProperty('assignees')) {
+        let newassignees = req.body.assignees;
+        if (_.isString(newassignees)) {
+          if (newassignees === '') {
+            newassignees = null;
+          } else {
+            newassignees = [newassignees];
+          }
+        }
+        Cards.direct.update(
+          {
+            _id: paramCardId,
+            listId: paramListId,
+            boardId: paramBoardId,
+            archived: false,
+          },
+          { $set: { assignees: newassignees } },
+        );
+      }
       if (req.body.hasOwnProperty('swimlaneId')) {
       if (req.body.hasOwnProperty('swimlaneId')) {
         const newParamSwimlaneId = req.body.swimlaneId;
         const newParamSwimlaneId = req.body.swimlaneId;
         Cards.direct.update(
         Cards.direct.update(