rulesHelper.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. RulesHelper = {
  2. executeRules(activity) {
  3. const matchingRules = this.findMatchingRules(activity);
  4. for (let i = 0; i < matchingRules.length; i++) {
  5. const action = matchingRules[i].getAction();
  6. if (action !== undefined) {
  7. this.performAction(activity, action);
  8. }
  9. }
  10. },
  11. findMatchingRules(activity) {
  12. const activityType = activity.activityType;
  13. if (TriggersDef[activityType] === undefined) {
  14. return [];
  15. }
  16. const matchingFields = TriggersDef[activityType].matchingFields;
  17. const matchingMap = this.buildMatchingFieldsMap(activity, matchingFields);
  18. const matchingTriggers = Triggers.find(matchingMap);
  19. const matchingRules = [];
  20. matchingTriggers.forEach(function(trigger) {
  21. const rule = trigger.getRule();
  22. // Check that for some unknown reason there are some leftover triggers
  23. // not connected to any rules
  24. if (rule !== undefined) {
  25. matchingRules.push(trigger.getRule());
  26. }
  27. });
  28. return matchingRules;
  29. },
  30. buildMatchingFieldsMap(activity, matchingFields) {
  31. const matchingMap = { activityType: activity.activityType };
  32. for (let i = 0; i < matchingFields.length; i++) {
  33. // Creating a matching map with the actual field of the activity
  34. // and with the wildcard (for example: trigger when a card is added
  35. // in any [*] board
  36. matchingMap[matchingFields[i]] = {
  37. $in: [activity[matchingFields[i]], '*'],
  38. };
  39. }
  40. return matchingMap;
  41. },
  42. performAction(activity, action) {
  43. const card = Cards.findOne({ _id: activity.cardId });
  44. const boardId = activity.boardId;
  45. if (action.actionType === 'moveCardToTop') {
  46. let listId;
  47. let list;
  48. if (action.listTitle === '*') {
  49. listId = card.listId;
  50. list = card.list();
  51. } else {
  52. list = Lists.findOne({ title: action.listTitle, boardId });
  53. listId = list._id;
  54. }
  55. const minOrder = _.min(
  56. list.cardsUnfiltered(card.swimlaneId).map(c => c.sort),
  57. );
  58. card.move(boardId, card.swimlaneId, listId, minOrder - 1);
  59. }
  60. if (action.actionType === 'moveCardToBottom') {
  61. let listId;
  62. let list;
  63. if (action.listTitle === '*') {
  64. listId = card.listId;
  65. list = card.list();
  66. } else {
  67. list = Lists.findOne({ title: action.listTitle, boardId });
  68. listId = list._id;
  69. }
  70. const maxOrder = _.max(
  71. list.cardsUnfiltered(card.swimlaneId).map(c => c.sort),
  72. );
  73. card.move(boardId, card.swimlaneId, listId, maxOrder + 1);
  74. }
  75. if (action.actionType === 'sendEmail') {
  76. const to = action.emailTo;
  77. const text = action.emailMsg || '';
  78. const subject = action.emailSubject || '';
  79. try {
  80. Email.send({
  81. to,
  82. from: Accounts.emailTemplates.from,
  83. subject,
  84. text,
  85. });
  86. } catch (e) {
  87. // eslint-disable-next-line no-console
  88. console.error(e);
  89. return;
  90. }
  91. }
  92. if (action.actionType === 'setDate') {
  93. try {
  94. const currentDateTime = new Date();
  95. switch (action.dateField) {
  96. case 'startAt': {
  97. const resStart = card.getStart();
  98. if (typeof resStart === 'undefined') {
  99. card.setStart(currentDateTime);
  100. }
  101. break;
  102. }
  103. case 'endAt': {
  104. const resEnd = card.getEnd();
  105. if (typeof resEnd === 'undefined') {
  106. card.setEnd(currentDateTime);
  107. }
  108. break;
  109. }
  110. case 'dueAt': {
  111. const resDue = card.getDue();
  112. if (typeof resDue === 'undefined') {
  113. card.setDue(currentDateTime);
  114. }
  115. break;
  116. }
  117. case 'receivedAt': {
  118. const resReceived = card.getReceived();
  119. if (typeof resReceived === 'undefined') {
  120. card.setReceived(currentDateTime);
  121. }
  122. break;
  123. }
  124. }
  125. } catch (e) {
  126. // eslint-disable-next-line no-console
  127. console.error(e);
  128. return;
  129. }
  130. }
  131. if (action.actionType === 'updateDate') {
  132. const currentDateTimeUpdate = new Date();
  133. switch (action.dateField) {
  134. case 'startAt': {
  135. card.setStart(currentDateTimeUpdate);
  136. break;
  137. }
  138. case 'endAt': {
  139. card.setEnd(currentDateTimeUpdate);
  140. break;
  141. }
  142. case 'dueAt': {
  143. card.setDue(currentDateTimeUpdate);
  144. break;
  145. }
  146. case 'receivedAt': {
  147. card.setReceived(currentDateTimeUpdate);
  148. break;
  149. }
  150. }
  151. }
  152. if (action.actionType === 'removeDate') {
  153. switch (action.dateField) {
  154. case 'startAt': {
  155. card.unsetStart();
  156. break;
  157. }
  158. case 'endAt': {
  159. card.unsetEnd();
  160. break;
  161. }
  162. case 'dueAt': {
  163. card.unsetDue();
  164. break;
  165. }
  166. case 'receivedAt': {
  167. card.unsetReceived();
  168. break;
  169. }
  170. }
  171. }
  172. if (action.actionType === 'archive') {
  173. card.archive();
  174. }
  175. if (action.actionType === 'unarchive') {
  176. card.restore();
  177. }
  178. if (action.actionType === 'setColor') {
  179. card.setColor(action.selectedColor);
  180. }
  181. if (action.actionType === 'addLabel') {
  182. card.addLabel(action.labelId);
  183. }
  184. if (action.actionType === 'removeLabel') {
  185. card.removeLabel(action.labelId);
  186. }
  187. if (action.actionType === 'addMember') {
  188. const memberId = Users.findOne({ username: action.username })._id;
  189. card.assignMember(memberId);
  190. }
  191. if (action.actionType === 'removeMember') {
  192. if (action.username === '*') {
  193. const members = card.members;
  194. for (let i = 0; i < members.length; i++) {
  195. card.unassignMember(members[i]);
  196. }
  197. } else {
  198. const memberId = Users.findOne({ username: action.username })._id;
  199. card.unassignMember(memberId);
  200. }
  201. }
  202. if (action.actionType === 'checkAll') {
  203. const checkList = Checklists.findOne({
  204. title: action.checklistName,
  205. cardId: card._id,
  206. });
  207. checkList.checkAllItems();
  208. }
  209. if (action.actionType === 'uncheckAll') {
  210. const checkList = Checklists.findOne({
  211. title: action.checklistName,
  212. cardId: card._id,
  213. });
  214. checkList.uncheckAllItems();
  215. }
  216. if (action.actionType === 'checkItem') {
  217. const checkList = Checklists.findOne({
  218. title: action.checklistName,
  219. cardId: card._id,
  220. });
  221. const checkItem = ChecklistItems.findOne({
  222. title: action.checkItemName,
  223. checkListId: checkList._id,
  224. });
  225. checkItem.check();
  226. }
  227. if (action.actionType === 'uncheckItem') {
  228. const checkList = Checklists.findOne({
  229. title: action.checklistName,
  230. cardId: card._id,
  231. });
  232. const checkItem = ChecklistItems.findOne({
  233. title: action.checkItemName,
  234. checkListId: checkList._id,
  235. });
  236. checkItem.uncheck();
  237. }
  238. if (action.actionType === 'addChecklist') {
  239. Checklists.insert({
  240. title: action.checklistName,
  241. cardId: card._id,
  242. sort: 0,
  243. });
  244. }
  245. if (action.actionType === 'removeChecklist') {
  246. Checklists.remove({
  247. title: action.checklistName,
  248. cardId: card._id,
  249. sort: 0,
  250. });
  251. }
  252. if (action.actionType === 'addSwimlane') {
  253. Swimlanes.insert({
  254. title: action.swimlaneName,
  255. boardId,
  256. sort: 0,
  257. });
  258. }
  259. if (action.actionType === 'addChecklistWithItems') {
  260. const checkListId = Checklists.insert({
  261. title: action.checklistName,
  262. cardId: card._id,
  263. sort: 0,
  264. });
  265. const itemsArray = action.checklistItems.split(',');
  266. const checkList = Checklists.findOne({ _id: checkListId });
  267. for (let i = 0; i < itemsArray.length; i++) {
  268. ChecklistItems.insert({
  269. title: itemsArray[i],
  270. checklistId: checkListId,
  271. cardId: card._id,
  272. sort: checkList.itemCount(),
  273. });
  274. }
  275. }
  276. if (action.actionType === 'createCard') {
  277. const list = Lists.findOne({ title: action.listName, boardId });
  278. let listId = '';
  279. let swimlaneId = '';
  280. const swimlane = Swimlanes.findOne({
  281. title: action.swimlaneName,
  282. boardId,
  283. });
  284. if (list === undefined) {
  285. listId = '';
  286. } else {
  287. listId = list._id;
  288. }
  289. if (swimlane === undefined) {
  290. swimlaneId = Swimlanes.findOne({ title: 'Default', boardId })._id;
  291. } else {
  292. swimlaneId = swimlane._id;
  293. }
  294. Cards.insert({
  295. title: action.cardName,
  296. listId,
  297. swimlaneId,
  298. sort: 0,
  299. boardId,
  300. });
  301. }
  302. },
  303. };