From d01fccd9497120613bf2c0b986963e67e7f3d6fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Manelli?= Date: Sat, 16 Mar 2019 22:43:47 +0100 Subject: - Fix card copy & move between boards with customFields - Fix card copy & move between boards with labels with same name - Fix activities for labels when copying and moving card - Fix activities for customFields when copying and moving card --- models/boards.js | 2 +- models/cards.js | 102 ++++++++++++++++++++++++++++++++++++++++++------- models/customFields.js | 61 ++++++++++++++++++++++++----- 3 files changed, 140 insertions(+), 25 deletions(-) (limited to 'models') diff --git a/models/boards.js b/models/boards.js index 9a71ede8..99ac8e6e 100644 --- a/models/boards.js +++ b/models/boards.js @@ -466,7 +466,7 @@ Boards.helpers({ }, customFields() { - return CustomFields.find({ boardId: this._id }, { sort: { name: 1 } }); + return CustomFields.find({ boardIds: {$in: [this._id]} }, { sort: { name: 1 } }); }, // XXX currently mutations return no value so we have an issue when using addLabel in import diff --git a/models/cards.js b/models/cards.js index 2caecb46..c234ab37 100644 --- a/models/cards.js +++ b/models/cards.js @@ -289,9 +289,19 @@ Cards.helpers({ const oldId = this._id; const oldCard = Cards.findOne(oldId); + // Copy Custom Fields + if (oldBoard._id !== boardId) { + CustomFields.find({ + _id: {$in: oldCard.customFields.map((cf) => { return cf._id; })}, + }).forEach((cf) => { + if (!_.contains(cf.boardIds, boardId)) + cf.addBoard(boardId); + }); + } + delete this._id; delete this.labelIds; - this.labelIds= newCardLabels; + this.labelIds = newCardLabels; this.boardId = boardId; this.swimlaneId = swimlaneId; this.listId = listId; @@ -306,7 +316,6 @@ Cards.helpers({ // copy checklists Checklists.find({cardId: oldId}).forEach((ch) => { - // REMOVE verify copy with arguments ch.copy(_id); }); @@ -314,13 +323,11 @@ Cards.helpers({ Cards.find({parentId: oldId}).forEach((subtask) => { subtask.parentId = _id; subtask._id = null; - // REMOVE verify copy with arguments instead of insert? Cards.insert(subtask); }); // copy card comments CardComments.find({cardId: oldId}).forEach((cmt) => { - // REMOVE verify copy with arguments cmt.copy(_id); }); @@ -485,6 +492,9 @@ Cards.helpers({ const definition = definitions.find((definition) => { return definition._id === customField._id; }); + if (!definition) { + return {}; + } //search for "True Value" which is for DropDowns other then the Value (which is the id) let trueValue = customField.value; if (definition.settings.dropdownItems && definition.settings.dropdownItems.length > 0) { @@ -1054,18 +1064,41 @@ Cards.mutations({ }; }, - move(swimlaneId, listId, sortIndex) { - const list = Lists.findOne(listId); + move(boardId, swimlaneId, listId, sort) { + // Copy Custom Fields + if (this.boardId !== boardId) { + CustomFields.find({ + _id: {$in: this.customFields.map((cf) => { return cf._id; })}, + }).forEach((cf) => { + if (!_.contains(cf.boardIds, boardId)) + cf.addBoard(boardId); + }); + } + + // Get label names + const oldBoard = Boards.findOne(this.boardId); + const oldBoardLabels = oldBoard.labels; + const oldCardLabels = _.pluck(_.filter(oldBoardLabels, (label) => { + return _.contains(this.labelIds, label._id); + }), 'name'); + + const newBoard = Boards.findOne(boardId); + const newBoardLabels = newBoard.labels; + const newCardLabelIds = _.pluck(_.filter(newBoardLabels, (label) => { + return label.name && _.contains(oldCardLabels, label.name); + }), '_id'); + const mutatedFields = { + boardId, swimlaneId, listId, - boardId: list.boardId, - sort: sortIndex, + sort, + labelIds: newCardLabelIds, }; - return { + Cards.update(this._id, { $set: mutatedFields, - }; + }); }, addLabel(labelId) { @@ -1287,8 +1320,47 @@ Cards.mutations({ //FUNCTIONS FOR creation of Activities -function cardMove(userId, doc, fieldNames, oldListId, oldSwimlaneId) { - if ((_.contains(fieldNames, 'listId') && doc.listId !== oldListId) || +function updateActivities(doc, fieldNames, modifier) { + if (_.contains(fieldNames, 'labelIds') && _.contains(fieldNames, 'boardId')) { + Activities.find({ + activityType: 'addedLabel', + cardId: doc._id, + }).forEach((a) => { + const lidx = doc.labelIds.indexOf(a.labelId); + if (lidx !== -1 && modifier.$set.labelIds.length > lidx) { + Activities.update(a._id, { + $set: { + labelId: modifier.$set.labelIds[doc.labelIds.indexOf(a.labelId)], + boardId: modifier.$set.boardId, + } + }); + } else { + Activities.remove(a._id); + } + }); + } else if (_.contains(fieldNames, 'boardId')) { + Activities.remove({ + activityType: 'addedLabel', + cardId: doc._id, + }); + } +} + +function cardMove(userId, doc, fieldNames, oldListId, oldSwimlaneId, oldBoardId) { + if (_.contains(fieldNames, 'boardId') && (doc.boardId !== oldBoardId)) { + Activities.insert({ + userId, + activityType: 'moveCardBoard', + boardName: Boards.findOne(doc.boardId).title, + boardId: doc.boardId, + oldBoardId, + oldBoardName: Boards.findOne(oldBoardId).title, + cardId: doc._id, + swimlaneName: Swimlanes.findOne(doc.swimlaneId).title, + swimlaneId: doc.swimlaneId, + oldSwimlaneId, + }); + } else if ((_.contains(fieldNames, 'listId') && doc.listId !== oldListId) || (_.contains(fieldNames, 'swimlaneId') && doc.swimlaneId !== oldSwimlaneId)){ Activities.insert({ userId, @@ -1435,7 +1507,7 @@ function cardCustomFields(userId, doc, fieldNames, modifier) { // only individual changes are registered if (dotNotation.length > 1) { - const customFieldId = doc.customFields[dot_notation[1]]._id; + const customFieldId = doc.customFields[dotNotation[1]]._id; const act = { userId, customFieldId, @@ -1508,12 +1580,14 @@ if (Meteor.isServer) { Cards.after.update(function(userId, doc, fieldNames) { const oldListId = this.previous.listId; const oldSwimlaneId = this.previous.swimlaneId; - cardMove(userId, doc, fieldNames, oldListId, oldSwimlaneId); + const oldBoardId = this.previous.boardId; + cardMove(userId, doc, fieldNames, oldListId, oldSwimlaneId, oldBoardId); }); // Add a new activity if we add or remove a member to the card Cards.before.update((userId, doc, fieldNames, modifier) => { cardMembers(userId, doc, fieldNames, modifier); + updateActivities(doc, fieldNames, modifier); }); // Add a new activity if we add or remove a label to the card diff --git a/models/customFields.js b/models/customFields.js index 79f96708..a67ddb7d 100644 --- a/models/customFields.js +++ b/models/customFields.js @@ -72,17 +72,37 @@ CustomFields.attachSchema(new SimpleSchema({ }, })); +CustomFields.mutations({ + addBoard(boardId) { + if (boardId) { + return { + $push: { + boardIds: boardId, + }, + }; + } else { + return null; + } + }, +}); + CustomFields.allow({ insert(userId, doc) { - return allowIsBoardMember(userId, Boards.findOne(doc.boardId)); + return allowIsAnyBoardMember(userId, Boards.find({ + _id: {$in: doc.boardIds}, + }).fetch()); }, update(userId, doc) { - return allowIsBoardMember(userId, Boards.findOne(doc.boardId)); + return allowIsAnyBoardMember(userId, Boards.find({ + _id: {$in: doc.boardIds}, + }).fetch()); }, remove(userId, doc) { - return allowIsBoardMember(userId, Boards.findOne(doc.boardId)); + return allowIsAnyBoardMember(userId, Boards.find({ + _id: {$in: doc.boardIds}, + }).fetch()); }, - fetch: ['userId', 'boardId'], + fetch: ['userId', 'boardIds'], }); // not sure if we need this? @@ -92,27 +112,48 @@ function customFieldCreation(userId, doc){ Activities.insert({ userId, activityType: 'createCustomField', - boardId: doc.boardId, + boardId: doc.boardIds[0], // We are creating a customField, it has only one boardId customFieldId: doc._id, }); } if (Meteor.isServer) { Meteor.startup(() => { - CustomFields._collection._ensureIndex({ boardId: 1 }); + CustomFields._collection._ensureIndex({ boardIds: 1 }); }); CustomFields.after.insert((userId, doc) => { customFieldCreation(userId, doc); }); - CustomFields.after.remove((userId, doc) => { + CustomFields.before.update((userId, doc, fieldNames, modifier) => { + if (_.contains(fieldNames, 'boardIds') && modifier.$pull) { + Cards.update( + {boardId: modifier.$pull.boardIds, 'customFields._id': doc._id}, + {$pull: {'customFields': {'_id': doc._id}}}, + {multi: true} + ); + Activities.remove({ + customFieldId: doc._id, + boardId: modifier.$pull.boardIds, + }); + } else if (_.contains(fieldNames, 'boardIds') && modifier.$push) { + Activities.insert({ + userId, + activityType: 'createCustomField', + boardId: modifier.$push.boardIds, + customFieldId: doc._id, + }); + } + }); + + CustomFields.before.remove((userId, doc) => { Activities.remove({ customFieldId: doc._id, }); Cards.update( - {'boardId': doc.boardId, 'customFields._id': doc._id}, + {boardId: {$in: doc.boardIds}, 'customFields._id': doc._id}, {$pull: {'customFields': {'_id': doc._id}}}, {multi: true} ); @@ -186,7 +227,7 @@ if (Meteor.isServer) { showOnCard: req.body.showOnCard, automaticallyOnCard: req.body.automaticallyOnCard, showLabelOnMiniCard: req.body.showLabelOnMiniCard, - boardId: paramBoardId, + boardIds: {$in: [paramBoardId]}, }); const customField = CustomFields.findOne({_id: id, boardIds: {$in: [paramBoardId]} }); @@ -214,7 +255,7 @@ if (Meteor.isServer) { Authentication.checkUserId( req.userId); const paramBoardId = req.params.boardId; const id = req.params.customFieldId; - CustomFields.remove({ _id: id, boardId: paramBoardId }); + CustomFields.remove({ _id: id, boardIds: {$in: [paramBoardId]} }); JsonRoutes.sendResult(res, { code: 200, data: { -- cgit v1.2.3-1-g7c22