rulesHelper.js 9.4 KB

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