- 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
This commit is contained in:
Andrés Manelli 2019-03-16 22:43:47 +01:00
parent 4cd0d1c397
commit d01fccd949
9 changed files with 179 additions and 34 deletions

View file

@ -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

View file

@ -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

View file

@ -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: {