123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401 |
- import { ReactiveCache } from '/imports/reactiveCache';
- RulesHelper = {
- executeRules(activity) {
- const matchingRules = this.findMatchingRules(activity);
- for (let i = 0; i < matchingRules.length; i++) {
- const action = matchingRules[i].getAction();
- if (action !== undefined) {
- this.performAction(activity, action);
- }
- }
- },
- findMatchingRules(activity) {
- const activityType = activity.activityType;
- if (TriggersDef[activityType] === undefined) {
- return [];
- }
- const matchingFields = TriggersDef[activityType].matchingFields;
- const matchingMap = this.buildMatchingFieldsMap(activity, matchingFields);
- const matchingTriggers = ReactiveCache.getTriggers(matchingMap);
- const matchingRules = [];
- matchingTriggers.forEach(function(trigger) {
- const rule = trigger.getRule();
- // Check that for some unknown reason there are some leftover triggers
- // not connected to any rules
- if (rule !== undefined) {
- matchingRules.push(trigger.getRule());
- }
- });
- return matchingRules;
- },
- buildMatchingFieldsMap(activity, matchingFields) {
- const matchingMap = { activityType: activity.activityType };
- matchingFields.forEach(field => {
- // Creating a matching map with the actual field of the activity
- // and with the wildcard (for example: trigger when a card is added
- // in any [*] board
- let value = activity[field];
- if (field === 'oldListName') {
- const oldList = ReactiveCache.getList(activity.oldListId);
- if (oldList) {
- value = oldList.title;
- }
- } else if (field === 'oldSwimlaneName') {
- const oldSwimlane = ReactiveCache.getSwimlane(activity.oldSwimlaneId);
- if (oldSwimlane) {
- value = oldSwimlane.title;
- }
- }
- let matchesList = [value, '*'];
- if ((field === 'cardTitle') && (value !== undefined)) {
- matchesList = value.split(/\W/).concat(matchesList);
- }
- matchingMap[field] = {
- $in: matchesList,
- };
- });
- return matchingMap;
- },
- performAction(activity, action) {
- const card = ReactiveCache.getCard(activity.cardId);
- const boardId = activity.boardId;
- if (
- action.actionType === 'moveCardToTop' ||
- action.actionType === 'moveCardToBottom'
- ) {
- let list;
- let listId;
- if (action.listName === '*') {
- list = card.list();
- if (boardId !== action.boardId) {
- list = ReactiveCache.getList({ title: list.title, boardId: action.boardId });
- }
- } else {
- list = ReactiveCache.getList({
- title: action.listName,
- boardId: action.boardId,
- });
- }
- if (list === undefined) {
- listId = '';
- } else {
- listId = list._id;
- }
- let swimlane;
- let swimlaneId;
- if (action.swimlaneName === '*') {
- swimlane = ReactiveCache.getSwimlane(card.swimlaneId);
- if (boardId !== action.boardId) {
- swimlane = ReactiveCache.getSwimlane({
- title: swimlane.title,
- boardId: action.boardId,
- });
- }
- } else {
- swimlane = ReactiveCache.getSwimlane({
- title: action.swimlaneName,
- boardId: action.boardId,
- });
- }
- if (swimlane === undefined) {
- swimlaneId = ReactiveCache.getSwimlane({
- title: 'Default',
- boardId: action.boardId,
- })._id;
- } else {
- swimlaneId = swimlane._id;
- }
- if (action.actionType === 'moveCardToTop') {
- const minOrder = _.min(
- list.cardsUnfiltered(swimlaneId).map(c => c.sort),
- );
- card.move(action.boardId, swimlaneId, listId, minOrder - 1);
- } else {
- const maxOrder = _.max(
- list.cardsUnfiltered(swimlaneId).map(c => c.sort),
- );
- card.move(action.boardId, swimlaneId, listId, maxOrder + 1);
- }
- }
- if (action.actionType === 'sendEmail') {
- const to = action.emailTo;
- const text = action.emailMsg || '';
- const subject = action.emailSubject || '';
- try {
- // Try to detect the recipient's language preference if it's a Wekan user
- // Otherwise, use the default language for the rule-triggered emails
- let recipientUser = null;
- let recipientLang = TAPi18n.getLanguage() || 'en';
- // Check if recipient is a Wekan user to get their language
- if (to && to.includes('@')) {
- recipientUser = ReactiveCache.getUser({ 'emails.address': to.toLowerCase() });
- if (recipientUser && typeof recipientUser.getLanguage === 'function') {
- recipientLang = recipientUser.getLanguage();
- }
- }
- // Use EmailLocalization if available
- if (typeof EmailLocalization !== 'undefined') {
- EmailLocalization.sendEmail({
- to,
- from: Accounts.emailTemplates.from,
- subject,
- text,
- language: recipientLang,
- userId: recipientUser ? recipientUser._id : null
- });
- } else {
- // Fallback to standard Email.send
- Email.send({
- to,
- from: Accounts.emailTemplates.from,
- subject,
- text,
- });
- }
- } catch (e) {
- // eslint-disable-next-line no-console
- console.error(e);
- return;
- }
- }
- if (action.actionType === 'setDate') {
- try {
- const currentDateTime = new Date();
- switch (action.dateField) {
- case 'startAt': {
- const resStart = card.getStart();
- if (typeof resStart === 'undefined') {
- card.setStart(currentDateTime);
- }
- break;
- }
- case 'endAt': {
- const resEnd = card.getEnd();
- if (typeof resEnd === 'undefined') {
- card.setEnd(currentDateTime);
- }
- break;
- }
- case 'dueAt': {
- const resDue = card.getDue();
- if (typeof resDue === 'undefined') {
- card.setDue(currentDateTime);
- }
- break;
- }
- case 'receivedAt': {
- const resReceived = card.getReceived();
- if (typeof resReceived === 'undefined') {
- card.setReceived(currentDateTime);
- }
- break;
- }
- }
- } catch (e) {
- // eslint-disable-next-line no-console
- console.error(e);
- return;
- }
- }
- if (action.actionType === 'updateDate') {
- const currentDateTimeUpdate = new Date();
- switch (action.dateField) {
- case 'startAt': {
- card.setStart(currentDateTimeUpdate);
- break;
- }
- case 'endAt': {
- card.setEnd(currentDateTimeUpdate);
- break;
- }
- case 'dueAt': {
- card.setDue(currentDateTimeUpdate);
- break;
- }
- case 'receivedAt': {
- card.setReceived(currentDateTimeUpdate);
- break;
- }
- }
- }
- if (action.actionType === 'removeDate') {
- switch (action.dateField) {
- case 'startAt': {
- card.unsetStart();
- break;
- }
- case 'endAt': {
- card.unsetEnd();
- break;
- }
- case 'dueAt': {
- card.unsetDue();
- break;
- }
- case 'receivedAt': {
- card.unsetReceived();
- break;
- }
- }
- }
- if (action.actionType === 'archive') {
- card.archive();
- }
- if (action.actionType === 'unarchive') {
- card.restore();
- }
- if (action.actionType === 'setColor') {
- card.setColor(action.selectedColor);
- }
- if (action.actionType === 'addLabel') {
- card.addLabel(action.labelId);
- }
- if (action.actionType === 'removeLabel') {
- card.removeLabel(action.labelId);
- }
- if (action.actionType === 'addMember') {
- const memberId = ReactiveCache.getUser({ username: action.username })._id;
- card.assignMember(memberId);
- }
- if (action.actionType === 'removeMember') {
- if (action.username === '*') {
- const members = card.members;
- for (let i = 0; i < members.length; i++) {
- card.unassignMember(members[i]);
- }
- } else {
- const memberId = ReactiveCache.getUser({ username: action.username })._id;
- card.unassignMember(memberId);
- }
- }
- if (action.actionType === 'checkAll') {
- const checkList = ReactiveCache.getChecklist({
- title: action.checklistName,
- cardId: card._id,
- });
- checkList.checkAllItems();
- }
- if (action.actionType === 'uncheckAll') {
- const checkList = ReactiveCache.getChecklist({
- title: action.checklistName,
- cardId: card._id,
- });
- checkList.uncheckAllItems();
- }
- if (action.actionType === 'checkItem') {
- const checkList = ReactiveCache.getChecklist({
- title: action.checklistName,
- cardId: card._id,
- });
- const checkItem = ReactiveCache.getChecklistItem({
- title: action.checkItemName,
- checkListId: checkList._id,
- });
- checkItem.check();
- }
- if (action.actionType === 'uncheckItem') {
- const checkList = ReactiveCache.getChecklist({
- title: action.checklistName,
- cardId: card._id,
- });
- const checkItem = ReactiveCache.getChecklistItem({
- title: action.checkItemName,
- checkListId: checkList._id,
- });
- checkItem.uncheck();
- }
- if (action.actionType === 'addChecklist') {
- Checklists.insert({
- title: action.checklistName,
- cardId: card._id,
- sort: 0,
- });
- }
- if (action.actionType === 'removeChecklist') {
- Checklists.remove({
- title: action.checklistName,
- cardId: card._id,
- sort: 0,
- });
- }
- if (action.actionType === 'addSwimlane') {
- Swimlanes.insert({
- title: action.swimlaneName,
- boardId,
- sort: 0,
- });
- }
- if (action.actionType === 'addChecklistWithItems') {
- const checkListId = Checklists.insert({
- title: action.checklistName,
- cardId: card._id,
- sort: 0,
- });
- const itemsArray = action.checklistItems.split(',');
- const checkList = ReactiveCache.getChecklist(checkListId);
- for (let i = 0; i < itemsArray.length; i++) {
- ChecklistItems.insert({
- title: itemsArray[i],
- checklistId: checkListId,
- cardId: card._id,
- sort: checkList.itemCount(),
- });
- }
- }
- if (action.actionType === 'createCard') {
- const list = ReactiveCache.getList({ title: action.listName, boardId });
- let listId = '';
- let swimlaneId = '';
- const swimlane = ReactiveCache.getSwimlane({
- title: action.swimlaneName,
- boardId,
- });
- if (list === undefined) {
- listId = '';
- } else {
- listId = list._id;
- }
- if (swimlane === undefined) {
- swimlaneId = ReactiveCache.getSwimlane({ title: 'Default', boardId })._id;
- } else {
- swimlaneId = swimlane._id;
- }
- Cards.insert({
- title: action.cardName,
- listId,
- swimlaneId,
- sort: 0,
- boardId
- });
- }
- if (action.actionType === 'linkCard') {
- const list = ReactiveCache.getList({ title: action.listName, boardId: action.boardId });
- const card = ReactiveCache.getCard(activity.cardId);
- let listId = '';
- let swimlaneId = '';
- const swimlane = ReactiveCache.getSwimlane({
- title: action.swimlaneName,
- boardId: action.boardId,
- });
- if (list === undefined) {
- listId = '';
- } else {
- listId = list._id;
- }
- if (swimlane === undefined) {
- swimlaneId = ReactiveCache.getSwimlane({ title: 'Default', boardId: action.boardId })._id;
- } else {
- swimlaneId = swimlane._id;
- }
- card.link(action.boardId, swimlaneId, listId);
- }
- },
- };
|