rulesHelper.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  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. matchingFields.forEach(field => {
  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. let value = activity[field];
  37. if (field === 'oldListName') {
  38. const oldList = Lists.findOne({ _id: activity.oldListId });
  39. if (oldList) {
  40. value = oldList.title;
  41. }
  42. } else if (field === 'oldSwimlaneName') {
  43. const oldSwimlane = Swimlanes.findOne({ _id: activity.oldSwimlaneId });
  44. if (oldSwimlane) {
  45. value = oldSwimlane.title;
  46. }
  47. }
  48. matchingMap[field] = {
  49. $in: [value, '*'],
  50. };
  51. });
  52. return matchingMap;
  53. },
  54. performAction(activity, action) {
  55. const card = Cards.findOne({ _id: activity.cardId });
  56. const boardId = activity.boardId;
  57. if (
  58. action.actionType === 'moveCardToTop' ||
  59. action.actionType === 'moveCardToBottom'
  60. ) {
  61. let list;
  62. let listId;
  63. if (action.listName === '*') {
  64. list = card.list();
  65. if (boardId !== action.boardId) {
  66. list = Lists.findOne({ title: list.title, boardId: action.boardId });
  67. }
  68. } else {
  69. list = Lists.findOne({
  70. title: action.listName,
  71. boardId: action.boardId,
  72. });
  73. }
  74. if (list === undefined) {
  75. listId = '';
  76. } else {
  77. listId = list._id;
  78. }
  79. let swimlane;
  80. let swimlaneId;
  81. if (action.swimlaneName === '*') {
  82. swimlane = Swimlanes.findOne(card.swimlaneId);
  83. if (boardId !== action.boardId) {
  84. swimlane = Swimlanes.findOne({
  85. title: swimlane.title,
  86. boardId: action.boardId,
  87. });
  88. }
  89. } else {
  90. swimlane = Swimlanes.findOne({
  91. title: action.swimlaneName,
  92. boardId: action.boardId,
  93. });
  94. }
  95. if (swimlane === undefined) {
  96. swimlaneId = Swimlanes.findOne({
  97. title: 'Default',
  98. boardId: action.boardId,
  99. })._id;
  100. } else {
  101. swimlaneId = swimlane._id;
  102. }
  103. if (action.actionType === 'moveCardToTop') {
  104. const minOrder = _.min(
  105. list.cardsUnfiltered(swimlaneId).map(c => c.sort),
  106. );
  107. card.move(action.boardId, swimlaneId, listId, minOrder - 1);
  108. } else {
  109. const maxOrder = _.max(
  110. list.cardsUnfiltered(swimlaneId).map(c => c.sort),
  111. );
  112. card.move(action.boardId, swimlaneId, listId, maxOrder + 1);
  113. }
  114. }
  115. if (action.actionType === 'sendEmail') {
  116. const to = action.emailTo;
  117. const text = action.emailMsg || '';
  118. const subject = action.emailSubject || '';
  119. try {
  120. Email.send({
  121. to,
  122. from: Accounts.emailTemplates.from,
  123. subject,
  124. text,
  125. });
  126. } catch (e) {
  127. // eslint-disable-next-line no-console
  128. console.error(e);
  129. return;
  130. }
  131. }
  132. if (action.actionType === 'setDate') {
  133. try {
  134. const currentDateTime = new Date();
  135. switch (action.dateField) {
  136. case 'startAt': {
  137. const resStart = card.getStart();
  138. if (typeof resStart === 'undefined') {
  139. card.setStart(currentDateTime);
  140. }
  141. break;
  142. }
  143. case 'endAt': {
  144. const resEnd = card.getEnd();
  145. if (typeof resEnd === 'undefined') {
  146. card.setEnd(currentDateTime);
  147. }
  148. break;
  149. }
  150. case 'dueAt': {
  151. const resDue = card.getDue();
  152. if (typeof resDue === 'undefined') {
  153. card.setDue(currentDateTime);
  154. }
  155. break;
  156. }
  157. case 'receivedAt': {
  158. const resReceived = card.getReceived();
  159. if (typeof resReceived === 'undefined') {
  160. card.setReceived(currentDateTime);
  161. }
  162. break;
  163. }
  164. }
  165. } catch (e) {
  166. // eslint-disable-next-line no-console
  167. console.error(e);
  168. return;
  169. }
  170. }
  171. if (action.actionType === 'updateDate') {
  172. const currentDateTimeUpdate = new Date();
  173. switch (action.dateField) {
  174. case 'startAt': {
  175. card.setStart(currentDateTimeUpdate);
  176. break;
  177. }
  178. case 'endAt': {
  179. card.setEnd(currentDateTimeUpdate);
  180. break;
  181. }
  182. case 'dueAt': {
  183. card.setDue(currentDateTimeUpdate);
  184. break;
  185. }
  186. case 'receivedAt': {
  187. card.setReceived(currentDateTimeUpdate);
  188. break;
  189. }
  190. }
  191. }
  192. if (action.actionType === 'removeDate') {
  193. switch (action.dateField) {
  194. case 'startAt': {
  195. card.unsetStart();
  196. break;
  197. }
  198. case 'endAt': {
  199. card.unsetEnd();
  200. break;
  201. }
  202. case 'dueAt': {
  203. card.unsetDue();
  204. break;
  205. }
  206. case 'receivedAt': {
  207. card.unsetReceived();
  208. break;
  209. }
  210. }
  211. }
  212. if (action.actionType === 'archive') {
  213. card.archive();
  214. }
  215. if (action.actionType === 'unarchive') {
  216. card.restore();
  217. }
  218. if (action.actionType === 'setColor') {
  219. card.setColor(action.selectedColor);
  220. }
  221. if (action.actionType === 'addLabel') {
  222. card.addLabel(action.labelId);
  223. }
  224. if (action.actionType === 'removeLabel') {
  225. card.removeLabel(action.labelId);
  226. }
  227. if (action.actionType === 'addMember') {
  228. const memberId = Users.findOne({ username: action.username })._id;
  229. card.assignMember(memberId);
  230. }
  231. if (action.actionType === 'removeMember') {
  232. if (action.username === '*') {
  233. const members = card.members;
  234. for (let i = 0; i < members.length; i++) {
  235. card.unassignMember(members[i]);
  236. }
  237. } else {
  238. const memberId = Users.findOne({ username: action.username })._id;
  239. card.unassignMember(memberId);
  240. }
  241. }
  242. if (action.actionType === 'checkAll') {
  243. const checkList = Checklists.findOne({
  244. title: action.checklistName,
  245. cardId: card._id,
  246. });
  247. checkList.checkAllItems();
  248. }
  249. if (action.actionType === 'uncheckAll') {
  250. const checkList = Checklists.findOne({
  251. title: action.checklistName,
  252. cardId: card._id,
  253. });
  254. checkList.uncheckAllItems();
  255. }
  256. if (action.actionType === 'checkItem') {
  257. const checkList = Checklists.findOne({
  258. title: action.checklistName,
  259. cardId: card._id,
  260. });
  261. const checkItem = ChecklistItems.findOne({
  262. title: action.checkItemName,
  263. checkListId: checkList._id,
  264. });
  265. checkItem.check();
  266. }
  267. if (action.actionType === 'uncheckItem') {
  268. const checkList = Checklists.findOne({
  269. title: action.checklistName,
  270. cardId: card._id,
  271. });
  272. const checkItem = ChecklistItems.findOne({
  273. title: action.checkItemName,
  274. checkListId: checkList._id,
  275. });
  276. checkItem.uncheck();
  277. }
  278. if (action.actionType === 'addChecklist') {
  279. Checklists.insert({
  280. title: action.checklistName,
  281. cardId: card._id,
  282. sort: 0,
  283. });
  284. }
  285. if (action.actionType === 'removeChecklist') {
  286. Checklists.remove({
  287. title: action.checklistName,
  288. cardId: card._id,
  289. sort: 0,
  290. });
  291. }
  292. if (action.actionType === 'addSwimlane') {
  293. Swimlanes.insert({
  294. title: action.swimlaneName,
  295. boardId,
  296. sort: 0,
  297. });
  298. }
  299. if (action.actionType === 'addChecklistWithItems') {
  300. const checkListId = Checklists.insert({
  301. title: action.checklistName,
  302. cardId: card._id,
  303. sort: 0,
  304. });
  305. const itemsArray = action.checklistItems.split(',');
  306. const checkList = Checklists.findOne({ _id: checkListId });
  307. for (let i = 0; i < itemsArray.length; i++) {
  308. ChecklistItems.insert({
  309. title: itemsArray[i],
  310. checklistId: checkListId,
  311. cardId: card._id,
  312. sort: checkList.itemCount(),
  313. });
  314. }
  315. }
  316. if (action.actionType === 'createCard') {
  317. const list = Lists.findOne({ title: action.listName, boardId });
  318. let listId = '';
  319. let swimlaneId = '';
  320. const swimlane = Swimlanes.findOne({
  321. title: action.swimlaneName,
  322. boardId,
  323. });
  324. if (list === undefined) {
  325. listId = '';
  326. } else {
  327. listId = list._id;
  328. }
  329. if (swimlane === undefined) {
  330. swimlaneId = Swimlanes.findOne({ title: 'Default', boardId })._id;
  331. } else {
  332. swimlaneId = swimlane._id;
  333. }
  334. Cards.insert({
  335. title: action.cardName,
  336. listId,
  337. swimlaneId,
  338. sort: 0,
  339. boardId,
  340. });
  341. }
  342. },
  343. };