diff --git a/.meteor/packages b/.meteor/packages index d65d3c515..1ae9aed82 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -20,7 +20,6 @@ reywood:publish-composite dburles:collection-helpers idmontie:migrations mongo@1.16.8 -mquandalle:collection-mutations # Account system accounts-password@2.4.0 diff --git a/.meteor/versions b/.meteor/versions index 65a815c21..e8b8793db 100644 --- a/.meteor/versions +++ b/.meteor/versions @@ -79,7 +79,6 @@ mongo-dev-server@1.1.0 mongo-id@1.0.8 mongo-livedata@1.0.12 mquandalle:autofocus@1.0.0 -mquandalle:collection-mutations@0.1.0 mquandalle:jade@0.4.9 mquandalle:jade-compiler@0.4.5 msavin:usercache@1.8.0 diff --git a/client/components/boards/boardArchive.js b/client/components/boards/boardArchive.js index c761bb69e..dcbc66066 100644 --- a/client/components/boards/boardArchive.js +++ b/client/components/boards/boardArchive.js @@ -23,7 +23,7 @@ BlazeComponent.extendComponent({ events() { return [ { - 'click .js-restore-board'() { + async 'click .js-restore-board'() { // TODO : Make isSandstorm variable global const isSandstorm = Meteor.settings && @@ -31,10 +31,10 @@ BlazeComponent.extendComponent({ Meteor.settings.public.sandstorm; if (isSandstorm && Utils.getCurrentBoardId()) { const currentBoard = Utils.getCurrentBoard(); - currentBoard.archive(); + await currentBoard.archive(); } const board = this.currentData(); - board.restore(); + await board.restore(); Utils.goBoardId(board._id); }, 'click .js-delete-board': Popup.afterConfirm('boardDelete', function() { diff --git a/client/components/boards/boardHeader.js b/client/components/boards/boardHeader.js index d9e1a99af..7317a7501 100644 --- a/client/components/boards/boardHeader.js +++ b/client/components/boards/boardHeader.js @@ -10,7 +10,7 @@ const UPCLS = 'fa-sort-up'; const sortCardsBy = new ReactiveVar(''); Template.boardChangeTitlePopup.events({ - submit(event, templateInstance) { + async submit(event, templateInstance) { const newTitle = templateInstance .$('.js-board-name') .val() @@ -20,8 +20,8 @@ Template.boardChangeTitlePopup.events({ .val() .trim(); if (newTitle) { - this.rename(newTitle); - this.setDescription(newDesc); + await this.rename(newTitle); + await this.setDescription(newDesc); Popup.back(); } event.preventDefault(); @@ -364,10 +364,10 @@ const CreateBoard = BlazeComponent.extendComponent({ }).register('createTemplateContainerPopup'); (class HeaderBarCreateBoard extends CreateBoard { - onSubmit(event) { + async onSubmit(event) { super.onSubmit(event); // Immediately star boards crated with the headerbar popup. - ReactiveCache.getCurrentUser().toggleBoardStar(this.boardId.get()); + await ReactiveCache.getCurrentUser().toggleBoardStar(this.boardId.get()); } }.register('headerBarCreateBoardPopup')); diff --git a/client/components/boards/boardsList.js b/client/components/boards/boardsList.js index d6a1b097e..166079b75 100644 --- a/client/components/boards/boardsList.js +++ b/client/components/boards/boardsList.js @@ -143,7 +143,7 @@ BlazeComponent.extendComponent({ ui.placeholder.height(ui.helper.height()); EscapeActions.executeUpTo('popup-close'); }, - stop(evt, ui) { + async stop(evt, ui) { const prevBoardDom = ui.item.prev('.js-board').get(0); const nextBoardDom = ui.item.next('.js-board').get(0); const sortIndex = Utils.calculateIndex(prevBoardDom, nextBoardDom, 1); @@ -153,7 +153,7 @@ BlazeComponent.extendComponent({ $boards.sortable('cancel'); const currentUser = ReactiveCache.getCurrentUser(); if (currentUser && typeof currentUser.setBoardSortIndex === 'function') { - currentUser.setBoardSortIndex(board._id, sortIndex.base); + await currentUser.setBoardSortIndex(board._id, sortIndex.base); } }, }); diff --git a/client/components/cards/cardDescription.js b/client/components/cards/cardDescription.js index c958c335e..8cf00f184 100644 --- a/client/components/cards/cardDescription.js +++ b/client/components/cards/cardDescription.js @@ -17,10 +17,10 @@ BlazeComponent.extendComponent({ events() { return [ { - 'submit .js-card-description'(event) { + async 'submit .js-card-description'(event) { event.preventDefault(); const description = this.currentComponent().getValue(); - this.data().setDescription(description); + await this.data().setDescription(description); }, // Pressing Ctrl+Enter should submit the form 'keydown form textarea'(evt) { diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 8c146369f..64708dd21 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -462,18 +462,18 @@ BlazeComponent.extendComponent({ const currentMode = Utils.getMobileMode(); Utils.setMobileMode(!currentMode); }, - 'submit .js-card-description'(event) { + async 'submit .js-card-description'(event) { event.preventDefault(); const description = this.currentComponent().getValue(); - this.data().setDescription(description); + await this.data().setDescription(description); }, - 'submit .js-card-details-title'(event) { + async 'submit .js-card-details-title'(event) { event.preventDefault(); const title = this.currentComponent().getValue().trim(); if (title) { - this.data().setTitle(title); + await this.data().setTitle(title); } else { - this.data().setTitle(''); + await this.data().setTitle(''); } }, 'submit .js-card-details-assigner'(event) { @@ -500,23 +500,23 @@ BlazeComponent.extendComponent({ this.find('button[type=submit]').click(); } }, - 'submit .js-card-details-sort'(event) { + async 'submit .js-card-details-sort'(event) { event.preventDefault(); const sort = parseFloat(this.currentComponent() .getValue() .trim()); if (!Number.isNaN(sort)) { let card = this.data(); - card.move(card.boardId, card.swimlaneId, card.listId, sort); + await card.move(card.boardId, card.swimlaneId, card.listId, sort); } }, - 'change .js-select-card-details-lists'(event) { + async 'change .js-select-card-details-lists'(event) { let card = this.data(); const listSelect = this.$('.js-select-card-details-lists')[0]; const listId = listSelect.options[listSelect.selectedIndex].value; const minOrder = card.getMinSort(listId, card.swimlaneId); - card.move(card.boardId, card.swimlaneId, listId, minOrder - 1); + await card.move(card.boardId, card.swimlaneId, listId, minOrder - 1); }, 'click .js-go-to-linked-card'() { Utils.goCardId(this.data().linkedId); @@ -554,8 +554,8 @@ BlazeComponent.extendComponent({ Session.set('cardDetailsIsDragging', false); Session.set('cardDetailsIsMouseDown', false); }, - 'click #toggleHideCheckedChecklistItems'() { - this.data().toggleHideCheckedChecklistItems(); + async 'click #toggleHideCheckedChecklistItems'() { + await this.data().toggleHideCheckedChecklistItems(); }, 'click #toggleCustomFieldsGridButton'() { Meteor.call('toggleCustomFieldsGrid'); @@ -862,21 +862,21 @@ Template.cardDetailsActionsPopup.events({ 'click .js-convert-checklist-item-to-card': Popup.open('convertChecklistItemToCard'), 'click .js-copy-checklist-cards': Popup.open('copyManyCards'), 'click .js-set-card-color': Popup.open('setCardColor'), - 'click .js-move-card-to-top'(event) { + async 'click .js-move-card-to-top'(event) { event.preventDefault(); const minOrder = this.getMinSort(); - this.move(this.boardId, this.swimlaneId, this.listId, minOrder - 1); + await this.move(this.boardId, this.swimlaneId, this.listId, minOrder - 1); Popup.back(); }, - 'click .js-move-card-to-bottom'(event) { + async 'click .js-move-card-to-bottom'(event) { event.preventDefault(); const maxOrder = this.getMaxSort(); - this.move(this.boardId, this.swimlaneId, this.listId, maxOrder + 1); + await this.move(this.boardId, this.swimlaneId, this.listId, maxOrder + 1); Popup.back(); }, - 'click .js-archive': Popup.afterConfirm('cardArchive', function () { + 'click .js-archive': Popup.afterConfirm('cardArchive', async function () { Popup.close(); - this.archive(); + await this.archive(); Utils.goBoardId(this.boardId); }), 'click .js-more': Popup.open('cardMore'), @@ -1011,11 +1011,11 @@ Template.editCardAssignerForm.events({ const ret = ReactiveCache.getCurrentUser().getMoveAndCopyDialogOptions(); return ret; } - setDone(cardId, options) { + async setDone(cardId, options) { ReactiveCache.getCurrentUser().setMoveAndCopyDialogOption(this.currentBoardId, options); const card = this.data(); let sortIndex = 0; - + if (cardId) { const targetCard = ReactiveCache.getCard(cardId); if (targetCard) { @@ -1030,8 +1030,8 @@ Template.editCardAssignerForm.events({ // If no card selected, move to end sortIndex = card.getMaxSort(options.listId, options.swimlaneId) + 1; } - - card.move(options.boardId, options.swimlaneId, options.listId, sortIndex); + + await card.move(options.boardId, options.swimlaneId, options.listId, sortIndex); } }).register('moveCardPopup'); @@ -1041,7 +1041,7 @@ Template.editCardAssignerForm.events({ const ret = ReactiveCache.getCurrentUser().getMoveAndCopyDialogOptions(); return ret; } - setDone(cardId, options) { + async setDone(cardId, options) { ReactiveCache.getCurrentUser().setMoveAndCopyDialogOption(this.currentBoardId, options); const card = this.data(); @@ -1056,7 +1056,7 @@ Template.editCardAssignerForm.events({ if (newCardId) { const newCard = ReactiveCache.getCard(newCardId); let sortIndex = 0; - + if (cardId) { const targetCard = ReactiveCache.getCard(cardId); if (targetCard) { @@ -1071,8 +1071,8 @@ Template.editCardAssignerForm.events({ // If no card selected, copy to end sortIndex = newCard.getMaxSort(options.listId, options.swimlaneId) + 1; } - - newCard.move(options.boardId, options.swimlaneId, options.listId, sortIndex); + + await newCard.move(options.boardId, options.swimlaneId, options.listId, sortIndex); } // In case the filter is active we need to add the newly inserted card in @@ -1090,7 +1090,7 @@ Template.editCardAssignerForm.events({ const ret = ReactiveCache.getCurrentUser().getMoveAndCopyDialogOptions(); return ret; } - setDone(cardId, options) { + async setDone(cardId, options) { ReactiveCache.getCurrentUser().setMoveAndCopyDialogOption(this.currentBoardId, options); const card = this.data(); @@ -1106,7 +1106,7 @@ Template.editCardAssignerForm.events({ sort: 0, }); const newCard = ReactiveCache.getCard(_id); - + let sortIndex = 0; if (cardId) { const targetCard = ReactiveCache.getCard(cardId); @@ -1121,8 +1121,8 @@ Template.editCardAssignerForm.events({ } else { sortIndex = newCard.getMaxSort(options.listId, options.swimlaneId) + 1; } - - newCard.move(options.boardId, options.swimlaneId, options.listId, sortIndex); + + await newCard.move(options.boardId, options.swimlaneId, options.listId, sortIndex); Filter.addException(_id); } @@ -1135,7 +1135,7 @@ Template.editCardAssignerForm.events({ const ret = ReactiveCache.getCurrentUser().getMoveAndCopyDialogOptions(); return ret; } - setDone(cardId, options) { + async setDone(cardId, options) { ReactiveCache.getCurrentUser().setMoveAndCopyDialogOption(this.currentBoardId, options); const card = this.data(); @@ -1151,7 +1151,7 @@ Template.editCardAssignerForm.events({ if (newCardId) { const newCard = ReactiveCache.getCard(newCardId); let sortIndex = 0; - + if (cardId) { const targetCard = ReactiveCache.getCard(cardId); if (targetCard) { @@ -1165,8 +1165,8 @@ Template.editCardAssignerForm.events({ } else { sortIndex = newCard.getMaxSort(options.listId, options.swimlaneId) + 1; } - - newCard.move(options.boardId, options.swimlaneId, options.listId, sortIndex); + + await newCard.move(options.boardId, options.swimlaneId, options.listId, sortIndex); } // In case the filter is active we need to add the newly inserted card in @@ -1202,14 +1202,14 @@ BlazeComponent.extendComponent({ 'click .js-palette-color'() { this.currentColor.set(this.currentData().color); }, - 'click .js-submit'(event) { + async 'click .js-submit'(event) { event.preventDefault(); - this.currentCard.setColor(this.currentColor.get()); + await this.currentCard.setColor(this.currentColor.get()); Popup.back(); }, - 'click .js-remove-color'(event) { + async 'click .js-remove-color'(event) { event.preventDefault(); - this.currentCard.setColor(null); + await this.currentCard.setColor(null); Popup.back(); }, }, @@ -1240,21 +1240,21 @@ BlazeComponent.extendComponent({ const color = colorClass ? colorClass.replace('card-details-', '') : null; this.currentColor.set(color); }, - 'click .js-submit'(event) { + async 'click .js-submit'(event) { event.preventDefault(); const color = this.currentColor.get(); // Use MultiSelection to get selected cards and set color on each - ReactiveCache.getCards(MultiSelection.getMongoSelector()).forEach(card => { - card.setColor(color); - }); + for (const card of ReactiveCache.getCards(MultiSelection.getMongoSelector())) { + await card.setColor(color); + } Popup.back(); }, - 'click .js-remove-color'(event) { + async 'click .js-remove-color'(event) { event.preventDefault(); // Use MultiSelection to get selected cards and remove color from each - ReactiveCache.getCards(MultiSelection.getMongoSelector()).forEach(card => { - card.setColor(null); - }); + for (const card of ReactiveCache.getCards(MultiSelection.getMongoSelector())) { + await card.setColor(null); + } Popup.back(); }, }, @@ -1866,7 +1866,7 @@ BlazeComponent.extendComponent({ // Close the card details pane by pressing escape EscapeActions.register( 'detailsPane', - () => { + async () => { // if card description diverges from database due to editing // ask user whether changes should be applied if (ReactiveCache.getCurrentUser()) { @@ -1874,7 +1874,7 @@ EscapeActions.register( currentDescription = document.getElementsByClassName("editor js-new-description-input").item(0) if (currentDescription?.value && !(currentDescription.value === Utils.getCurrentCard().getDescription())) { if (confirm(TAPi18n.__('rescue-card-description-dialogue'))) { - Utils.getCurrentCard().setDescription(document.getElementsByClassName("editor js-new-description-input").item(0).value); + await Utils.getCurrentCard().setDescription(document.getElementsByClassName("editor js-new-description-input").item(0).value); // Save it! console.log(document.getElementsByClassName("editor js-new-description-input").item(0).value); console.log("current description", Utils.getCurrentCard().getDescription()); diff --git a/client/components/cards/checklists.js b/client/components/cards/checklists.js index 15a9b9fa1..459fdeb0a 100644 --- a/client/components/cards/checklists.js +++ b/client/components/cards/checklists.js @@ -157,21 +157,21 @@ BlazeComponent.extendComponent({ textarea.focus(); }, - editChecklist(event) { + async editChecklist(event) { event.preventDefault(); const textarea = this.find('textarea.js-edit-checklist-item'); const title = textarea.value.trim(); const checklist = this.currentData().checklist; - checklist.setTitle(title); + await checklist.setTitle(title); }, - editChecklistItem(event) { + async editChecklistItem(event) { event.preventDefault(); const textarea = this.find('textarea.js-edit-checklist-item'); const title = textarea.value.trim(); const item = this.currentData().item; - item.setTitle(title); + await item.setTitle(title); }, pressKey(event) { @@ -321,20 +321,20 @@ BlazeComponent.extendComponent({ }, 'click .js-move-checklist': Popup.open('moveChecklist'), 'click .js-copy-checklist': Popup.open('copyChecklist'), - 'click .js-hide-checked-checklist-items'(event) { + async 'click .js-hide-checked-checklist-items'(event) { event.preventDefault(); - this.data().checklist.toggleHideCheckedChecklistItems(); + await this.data().checklist.toggleHideCheckedChecklistItems(); Popup.back(); }, - 'click .js-hide-all-checklist-items'(event) { + async 'click .js-hide-all-checklist-items'(event) { event.preventDefault(); - this.data().checklist.toggleHideAllChecklistItems(); + await this.data().checklist.toggleHideAllChecklistItems(); Popup.back(); }, - 'click .js-toggle-show-checklist-at-minicard'(event) { + async 'click .js-toggle-show-checklist-at-minicard'(event) { event.preventDefault(); const checklist = this.data().checklist; - checklist.toggleShowChecklistAtMinicard(); + await checklist.toggleShowChecklistAtMinicard(); Popup.back(); }, } @@ -365,11 +365,11 @@ Template.checklistItemDetail.helpers({ }); BlazeComponent.extendComponent({ - toggleItem() { + async toggleItem() { const checklist = this.currentData().checklist; const item = this.currentData().item; if (checklist && item && item._id) { - item.toggleItem(); + await item.toggleItem(); } }, events() { diff --git a/client/components/cards/minicard.js b/client/components/cards/minicard.js index 194f37ee9..22ce35e62 100644 --- a/client/components/cards/minicard.js +++ b/client/components/cards/minicard.js @@ -91,10 +91,10 @@ BlazeComponent.extendComponent({ } }, - toggleChecklistItem() { + async toggleChecklistItem() { const item = this.currentData(); if (item && item._id) { - item.toggleItem(); + await item.toggleItem(); } }, @@ -319,15 +319,15 @@ Template.cardDetailsActionsPopup.events({ this.move(this.boardId, this.swimlaneId, this.listId, minOrder - 1); Popup.back(); }, - 'click .js-move-card-to-bottom'(event) { + async 'click .js-move-card-to-bottom'(event) { event.preventDefault(); const maxOrder = this.getMaxSort(); - this.move(this.boardId, this.swimlaneId, this.listId, maxOrder + 1); + await this.move(this.boardId, this.swimlaneId, this.listId, maxOrder + 1); Popup.back(); }, - 'click .js-archive': Popup.afterConfirm('cardArchive', function () { + 'click .js-archive': Popup.afterConfirm('cardArchive', async function () { Popup.close(); - this.archive(); + await this.archive(); Utils.goBoardId(this.boardId); }), 'click .js-toggle-watch-card'() { diff --git a/client/components/cards/subtasks.js b/client/components/cards/subtasks.js index 4396890e5..d0d19438c 100644 --- a/client/components/cards/subtasks.js +++ b/client/components/cards/subtasks.js @@ -62,10 +62,10 @@ BlazeComponent.extendComponent({ textarea.focus(); }, - deleteSubtask() { + async deleteSubtask() { const subtask = this.currentData().subtask; if (subtask && subtask._id) { - subtask.archive(); + await subtask.archive(); } }, @@ -73,12 +73,12 @@ BlazeComponent.extendComponent({ return ReactiveCache.getCurrentUser().isBoardAdmin(); }, - editSubtask(event) { + async editSubtask(event) { event.preventDefault(); const textarea = this.find('textarea.js-edit-subtask-item'); const title = textarea.value.trim(); const subtask = this.currentData().subtask; - subtask.setTitle(title); + await subtask.setTitle(title); }, pressKey(event) { @@ -105,10 +105,10 @@ BlazeComponent.extendComponent({ }).register('subtasks'); BlazeComponent.extendComponent({ - toggleItem() { + async toggleItem() { const item = this.currentData().item; if (item && item._id) { - item.toggleItem(); + await item.toggleItem(); } }, events() { @@ -138,11 +138,11 @@ BlazeComponent.extendComponent({ }); } }, - 'click .js-delete-subtask' : Popup.afterConfirm('subtaskDelete', function () { + 'click .js-delete-subtask' : Popup.afterConfirm('subtaskDelete', async function () { Popup.back(2); const subtask = this.subtask; if (subtask && subtask._id) { - subtask.archive(); + await subtask.archive(); } }), } diff --git a/client/components/lists/listHeader.js b/client/components/lists/listHeader.js index 2e57e694e..cf860877f 100644 --- a/client/components/lists/listHeader.js +++ b/client/components/lists/listHeader.js @@ -22,14 +22,14 @@ BlazeComponent.extendComponent({ isBoardAdmin() { return ReactiveCache.getCurrentUser().isBoardAdmin(); }, - starred(check = undefined) { + async starred(check = undefined) { const list = Template.currentData(); const status = list.isStarred(); if (check === undefined) { // just check return status; } else { - list.star(!status); + await list.star(!status); return !status; } }, @@ -45,14 +45,14 @@ BlazeComponent.extendComponent({ return next; } }, - editTitle(event) { + async editTitle(event) { event.preventDefault(); const newTitle = this.childComponents('inlinedForm')[0] .getValue() .trim(); const list = this.currentData(); if (newTitle) { - list.rename(newTitle.trim()); + await list.rename(newTitle.trim()); } }, @@ -226,9 +226,9 @@ Template.listActionPopup.events({ if (!err && ret) Popup.back(); }); }, - 'click .js-close-list'(event) { + async 'click .js-close-list'(event) { event.preventDefault(); - this.archive(); + await this.archive(); Popup.back(); }, 'click .js-set-wip-limit': Popup.open('setWipLimit'), @@ -255,26 +255,26 @@ BlazeComponent.extendComponent({ } }, - enableSoftLimit() { + async enableSoftLimit() { const list = Template.currentData(); if ( list.getWipLimit('soft') && list.getWipLimit('value') < list.cards().length ) { - list.setWipLimit(list.cards().length); + await list.setWipLimit(list.cards().length); } Meteor.call('enableSoftLimit', Template.currentData()._id); }, - enableWipLimit() { + async enableWipLimit() { const list = Template.currentData(); // Prevent user from using previously stored wipLimit.value if it is less than the current number of cards in the list if ( !list.getWipLimit('enabled') && list.getWipLimit('value') < list.cards().length ) { - list.setWipLimit(list.cards().length); + await list.setWipLimit(list.cards().length); } Meteor.call('enableWipLimit', list._id); }, @@ -368,12 +368,12 @@ BlazeComponent.extendComponent({ 'click .js-palette-color'() { this.currentColor.set(this.currentData().color); }, - 'click .js-submit'() { - this.currentList.setColor(this.currentColor.get()); + async 'click .js-submit'() { + await this.currentList.setColor(this.currentColor.get()); Popup.close(); }, - 'click .js-remove-color'() { - this.currentList.setColor(null); + async 'click .js-remove-color'() { + await this.currentList.setColor(null); Popup.close(); }, }, diff --git a/client/components/main/bookmarks.js b/client/components/main/bookmarks.js index 6ec110593..2e0504960 100644 --- a/client/components/main/bookmarks.js +++ b/client/components/main/bookmarks.js @@ -15,12 +15,12 @@ Template.bookmarks.helpers({ }); Template.bookmarks.events({ - 'click .js-toggle-star'(e) { + async 'click .js-toggle-star'(e) { e.preventDefault(); const boardId = this._id; const user = ReactiveCache.getCurrentUser(); if (user && boardId) { - user.toggleBoardStar(boardId); + await user.toggleBoardStar(boardId); } }, }); @@ -42,12 +42,12 @@ Template.bookmarksPopup.helpers({ }); Template.bookmarksPopup.events({ - 'click .js-toggle-star'(e) { + async 'click .js-toggle-star'(e) { e.preventDefault(); const boardId = this._id; const user = ReactiveCache.getCurrentUser(); if (user && boardId) { - user.toggleBoardStar(boardId); + await user.toggleBoardStar(boardId); } }, }); diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js index bda802102..f09f09c3f 100644 --- a/client/components/sidebar/sidebar.js +++ b/client/components/sidebar/sidebar.js @@ -327,9 +327,9 @@ Template.boardMenuPopup.events({ // You could add a toast notification here if available } }), - 'click .js-archive-board ': Popup.afterConfirm('archiveBoard', function() { + 'click .js-archive-board ': Popup.afterConfirm('archiveBoard', async function() { const currentBoard = Utils.getCurrentBoard(); - currentBoard.archive(); + await currentBoard.archive(); // XXX We should have some kind of notification on top of the page to // confirm that the board was successfully archived. FlowRouter.go('home'); @@ -382,7 +382,7 @@ Template.memberPopup.events({ Popup.back(); }, 'click .js-change-role': Popup.open('changePermissions'), - 'click .js-remove-member': Popup.afterConfirm('removeMember', function() { + 'click .js-remove-member': Popup.afterConfirm('removeMember', async function() { // This works from removing member from board, card members and assignees. const boardId = Session.get('currentBoard'); const memberId = this.userId; @@ -392,7 +392,7 @@ Template.memberPopup.events({ ReactiveCache.getCards({ boardId, assignees: memberId }).forEach(card => { card.unassignAssignee(memberId); }); - ReactiveCache.getBoard(boardId).removeMember(memberId); + await ReactiveCache.getBoard(boardId).removeMember(memberId); Popup.back(); }), 'click .js-leave-member': Popup.afterConfirm('leaveBoard', () => { @@ -774,10 +774,10 @@ BlazeComponent.extendComponent({ events() { return [ { - 'click .js-select-background'(evt) { + async 'click .js-select-background'(evt) { const currentBoard = Utils.getCurrentBoard(); const newColor = this.currentData().toString(); - currentBoard.setColor(newColor); + await currentBoard.setColor(newColor); evt.preventDefault(); }, }, @@ -789,10 +789,10 @@ BlazeComponent.extendComponent({ events() { return [ { - submit(event) { + async submit(event) { const currentBoard = Utils.getCurrentBoard(); const backgroundImageURL = this.find('.js-board-background-image-url').value.trim(); - currentBoard.setBackgroundImageURL(backgroundImageURL); + await currentBoard.setBackgroundImageURL(backgroundImageURL); Utils.setBackgroundImage(); Popup.back(); event.preventDefault(); @@ -1945,7 +1945,7 @@ Template.removeBoardTeamPopup.helpers({ }); Template.changePermissionsPopup.events({ - 'click .js-set-admin, click .js-set-normal, click .js-set-normal-assigned-only, click .js-set-no-comments, click .js-set-comment-only, click .js-set-comment-assigned-only, click .js-set-read-only, click .js-set-read-assigned-only, click .js-set-worker'( + async 'click .js-set-admin, click .js-set-normal, click .js-set-normal-assigned-only, click .js-set-no-comments, click .js-set-comment-only, click .js-set-comment-assigned-only, click .js-set-read-only, click .js-set-read-assigned-only, click .js-set-worker'( event, ) { const currentBoard = Utils.getCurrentBoard(); @@ -1964,7 +1964,7 @@ Template.changePermissionsPopup.events({ const isReadAssignedOnly = $(event.currentTarget).hasClass('js-set-read-assigned-only'); const isNoComments = $(event.currentTarget).hasClass('js-set-no-comments'); const isWorker = $(event.currentTarget).hasClass('js-set-worker'); - currentBoard.setMemberPermission( + await currentBoard.setMemberPermission( memberId, isAdmin, isNoComments, diff --git a/client/components/sidebar/sidebarArchives.js b/client/components/sidebar/sidebarArchives.js index f79e601ee..9b15897a9 100644 --- a/client/components/sidebar/sidebarArchives.js +++ b/client/components/sidebar/sidebarArchives.js @@ -81,18 +81,18 @@ BlazeComponent.extendComponent({ events() { return [ { - 'click .js-restore-card'() { + async 'click .js-restore-card'() { const card = this.currentData(); if (card.canBeRestored()) { - card.restore(); + await card.restore(); } }, - 'click .js-restore-all-cards'() { - this.archivedCards().forEach(card => { + async 'click .js-restore-all-cards'() { + for (const card of this.archivedCards()) { if (card.canBeRestored()) { - card.restore(); + await card.restore(); } - }); + } }, 'click .js-delete-card': Popup.afterConfirm('cardDelete', function() { @@ -107,14 +107,14 @@ BlazeComponent.extendComponent({ Popup.back(); }), - 'click .js-restore-list'() { + async 'click .js-restore-list'() { const list = this.currentData(); - list.restore(); + await list.restore(); }, - 'click .js-restore-all-lists'() { - this.archivedLists().forEach(list => { - list.restore(); - }); + async 'click .js-restore-all-lists'() { + for (const list of this.archivedLists()) { + await list.restore(); + } }, 'click .js-delete-list': Popup.afterConfirm('listDelete', function() { @@ -128,14 +128,14 @@ BlazeComponent.extendComponent({ Popup.back(); }), - 'click .js-restore-swimlane'() { + async 'click .js-restore-swimlane'() { const swimlane = this.currentData(); - swimlane.restore(); + await swimlane.restore(); }, - 'click .js-restore-all-swimlanes'() { - this.archivedSwimlanes().forEach(swimlane => { - swimlane.restore(); - }); + async 'click .js-restore-all-swimlanes'() { + for (const swimlane of this.archivedSwimlanes()) { + await swimlane.restore(); + } }, 'click .js-delete-swimlane': Popup.afterConfirm( diff --git a/client/components/swimlanes/swimlaneHeader.js b/client/components/swimlanes/swimlaneHeader.js index 1caeda34c..943e003cd 100644 --- a/client/components/swimlanes/swimlaneHeader.js +++ b/client/components/swimlanes/swimlaneHeader.js @@ -8,14 +8,14 @@ Meteor.startup(() => { }); BlazeComponent.extendComponent({ - editTitle(event) { + async editTitle(event) { event.preventDefault(); const newTitle = this.childComponents('inlinedForm')[0] .getValue() .trim(); const swimlane = this.currentData(); if (newTitle) { - swimlane.rename(newTitle.trim()); + await swimlane.rename(newTitle.trim()); } }, collapsed(check = undefined) { @@ -106,9 +106,9 @@ Template.editSwimlaneTitleForm.helpers({ Template.swimlaneActionPopup.events({ 'click .js-set-swimlane-color': Popup.open('setSwimlaneColor'), 'click .js-set-swimlane-height': Popup.open('setSwimlaneHeight'), - 'click .js-close-swimlane'(event) { + async 'click .js-close-swimlane'(event) { event.preventDefault(); - this.archive(); + await this.archive(); Popup.back(); }, 'click .js-move-swimlane': Popup.open('moveSwimlane'), @@ -183,20 +183,20 @@ BlazeComponent.extendComponent({ events() { return [ { - 'submit form'(event) { + async 'submit form'(event) { event.preventDefault(); - this.currentSwimlane.setColor(this.currentColor.get()); + await this.currentSwimlane.setColor(this.currentColor.get()); Popup.back(); }, 'click .js-palette-color'() { this.currentColor.set(this.currentData().color); }, - 'click .js-submit'() { - this.currentSwimlane.setColor(this.currentColor.get()); + async 'click .js-submit'() { + await this.currentSwimlane.setColor(this.currentColor.get()); Popup.back(); }, - 'click .js-remove-color'() { - this.currentSwimlane.setColor(null); + async 'click .js-remove-color'() { + await this.currentSwimlane.setColor(null); Popup.back(); }, }, diff --git a/client/lib/keyboard.js b/client/lib/keyboard.js index e06a6463e..7a72df472 100644 --- a/client/lib/keyboard.js +++ b/client/lib/keyboard.js @@ -268,7 +268,7 @@ hotkeys('space', (event) => { } }); -const archiveCard = (event) => { +const archiveCard = async (event) => { event.preventDefault(); const cardId = getSelectedCardId(); if (!cardId) { @@ -282,7 +282,7 @@ const archiveCard = (event) => { if (Utils.canModifyBoard()) { const card = Cards.findOne(cardId); - card.archive(); + await card.archive(); } }; diff --git a/client/lib/utils.js b/client/lib/utils.js index 52f4a0ac3..735e23025 100644 --- a/client/lib/utils.js +++ b/client/lib/utils.js @@ -2,14 +2,14 @@ import { ReactiveCache } from '/imports/reactiveCache'; import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; Utils = { - setBackgroundImage(url) { + async setBackgroundImage(url) { const currentBoard = Utils.getCurrentBoard(); if (currentBoard.backgroundImageURL !== undefined) { $(".board-wrapper").css({"background":"url(" + currentBoard.backgroundImageURL + ")","background-size":"cover"}); $(".swimlane,.swimlane .list,.swimlane .list .list-body,.swimlane .list:first-child .list-body").css({"background-color":"transparent"}); $(".minicard").css({"opacity": "0.9"}); } else if (currentBoard["background-color"]) { - currentBoard.setColor(currentBoard["background-color"]); + await currentBoard.setColor(currentBoard["background-color"]); } }, /** returns the current board id diff --git a/models/boards.js b/models/boards.js index 56f21f37d..5afff4034 100644 --- a/models/boards.js +++ b/models/boards.js @@ -1431,93 +1431,80 @@ Boards.helpers({ isTemplatesBoard() { return this.type === 'template-container'; }, -}); -Boards.mutations({ - archive() { - return { $set: { archived: true, archivedAt: new Date() } }; + async archive() { + return await Boards.updateAsync(this._id, { $set: { archived: true, archivedAt: new Date() } }); }, - restore() { - return { $set: { archived: false } }; + async restore() { + return await Boards.updateAsync(this._id, { $set: { archived: false } }); }, - rename(title) { - return { $set: { title } }; + async rename(title) { + return await Boards.updateAsync(this._id, { $set: { title } }); }, - setDescription(description) { - return { $set: { description } }; + async setDescription(description) { + return await Boards.updateAsync(this._id, { $set: { description } }); }, - setColor(color) { - return { $set: { color } }; + async setColor(color) { + return await Boards.updateAsync(this._id, { $set: { color } }); }, - setBackgroundImageURL(backgroundImageURL) { + async setBackgroundImageURL(backgroundImageURL) { const currentUser = ReactiveCache.getCurrentUser(); - if(currentUser.isBoardAdmin()) { - return { $set: { backgroundImageURL } }; - } else if (currentUser.isAdmin()) { - return { $set: { backgroundImageURL } }; - } else { - return false; + if (currentUser.isBoardAdmin() || currentUser.isAdmin()) { + return await Boards.updateAsync(this._id, { $set: { backgroundImageURL } }); } + return false; }, - setVisibility(visibility) { - return { $set: { permission: visibility } }; + async setVisibility(visibility) { + return await Boards.updateAsync(this._id, { $set: { permission: visibility } }); }, - addLabel(name, color) { - // If label with the same name and color already exists we don't want to - // create another one because they would be indistinguishable in the UI - // (they would still have different `_id` but that is not exposed to the - // user). + async addLabel(name, color) { if (!this.getLabel(name, color)) { const _id = Random.id(6); - return { $push: { labels: { _id, name, color } } }; + return await Boards.updateAsync(this._id, { $push: { labels: { _id, name, color } } }); } - return {}; + return null; }, - editLabel(labelId, name, color) { + async editLabel(labelId, name, color) { if (!this.getLabel(name, color)) { const labelIndex = this.labelIndex(labelId); - return { + return await Boards.updateAsync(this._id, { $set: { [`labels.${labelIndex}.name`]: name, [`labels.${labelIndex}.color`]: color, }, - }; + }); } - return {}; + return null; }, - removeLabel(labelId) { - return { $pull: { labels: { _id: labelId } } }; + async removeLabel(labelId) { + return await Boards.updateAsync(this._id, { $pull: { labels: { _id: labelId } } }); }, - changeOwnership(fromId, toId) { + async changeOwnership(fromId, toId) { const memberIndex = this.memberIndex(fromId); - return { - $set: { - [`members.${memberIndex}.userId`]: toId, - }, - }; + return await Boards.updateAsync(this._id, { + $set: { [`members.${memberIndex}.userId`]: toId }, + }); }, - addMember(memberId) { + async addMember(memberId) { const memberIndex = this.memberIndex(memberId); if (memberIndex >= 0) { - return { - $set: { - [`members.${memberIndex}.isActive`]: true, - }, - }; + return await Boards.updateAsync(this._id, { + $set: { [`members.${memberIndex}.isActive`]: true }, + }); } - return { + return await Boards.updateAsync(this._id, { $push: { members: { userId: memberId, @@ -1532,32 +1519,28 @@ Boards.mutations({ isReadAssignedOnly: false, }, }, - }; + }); }, - removeMember(memberId) { + async removeMember(memberId) { const memberIndex = this.memberIndex(memberId); - - // we do not allow the only one admin to be removed const allowRemove = !this.members[memberIndex].isAdmin || this.activeAdmins().length > 1; if (!allowRemove) { - return { - $set: { - [`members.${memberIndex}.isActive`]: true, - }, - }; + return await Boards.updateAsync(this._id, { + $set: { [`members.${memberIndex}.isActive`]: true }, + }); } - return { + return await Boards.updateAsync(this._id, { $set: { [`members.${memberIndex}.isActive`]: false, [`members.${memberIndex}.isAdmin`]: false, }, - }; + }); }, - setMemberPermission( + async setMemberPermission( memberId, isAdmin, isNoComments, @@ -1570,12 +1553,11 @@ Boards.mutations({ currentUserId = Meteor.userId(), ) { const memberIndex = this.memberIndex(memberId); - // do not allow change permission of self if (memberId === currentUserId) { isAdmin = this.members[memberIndex].isAdmin; } - return { + return await Boards.updateAsync(this._id, { $set: { [`members.${memberIndex}.isAdmin`]: isAdmin, [`members.${memberIndex}.isNoComments`]: isNoComments, @@ -1586,144 +1568,143 @@ Boards.mutations({ [`members.${memberIndex}.isReadOnly`]: isReadOnly, [`members.${memberIndex}.isReadAssignedOnly`]: isReadAssignedOnly, }, - }; + }); }, - setAllowsSubtasks(allowsSubtasks) { - return { $set: { allowsSubtasks } }; + async setAllowsSubtasks(allowsSubtasks) { + return await Boards.updateAsync(this._id, { $set: { allowsSubtasks } }); }, - setAllowsCreator(allowsCreator) { - return { $set: { allowsCreator } }; + async setAllowsCreator(allowsCreator) { + return await Boards.updateAsync(this._id, { $set: { allowsCreator } }); }, - setAllowsCreatorOnMinicard(allowsCreatorOnMinicard) { - return { $set: { allowsCreatorOnMinicard } }; + async setAllowsCreatorOnMinicard(allowsCreatorOnMinicard) { + return await Boards.updateAsync(this._id, { $set: { allowsCreatorOnMinicard } }); }, - setAllowsMembers(allowsMembers) { - return { $set: { allowsMembers } }; + async setAllowsMembers(allowsMembers) { + return await Boards.updateAsync(this._id, { $set: { allowsMembers } }); }, - setAllowsChecklists(allowsChecklists) { - return { $set: { allowsChecklists } }; + async setAllowsChecklists(allowsChecklists) { + return await Boards.updateAsync(this._id, { $set: { allowsChecklists } }); }, - setAllowsAssignee(allowsAssignee) { - return { $set: { allowsAssignee } }; + async setAllowsAssignee(allowsAssignee) { + return await Boards.updateAsync(this._id, { $set: { allowsAssignee } }); }, - setAllowsAssignedBy(allowsAssignedBy) { - return { $set: { allowsAssignedBy } }; + async setAllowsAssignedBy(allowsAssignedBy) { + return await Boards.updateAsync(this._id, { $set: { allowsAssignedBy } }); }, - setAllowsShowListsOnMinicard(allowsShowListsOnMinicard) { - return { $set: { allowsShowListsOnMinicard } }; + async setAllowsShowListsOnMinicard(allowsShowListsOnMinicard) { + return await Boards.updateAsync(this._id, { $set: { allowsShowListsOnMinicard } }); }, - setAllowsChecklistAtMinicard(allowsChecklistAtMinicard) { - return { $set: { allowsChecklistAtMinicard } }; + async setAllowsChecklistAtMinicard(allowsChecklistAtMinicard) { + return await Boards.updateAsync(this._id, { $set: { allowsChecklistAtMinicard } }); }, - setAllowsRequestedBy(allowsRequestedBy) { - return { $set: { allowsRequestedBy } }; + async setAllowsRequestedBy(allowsRequestedBy) { + return await Boards.updateAsync(this._id, { $set: { allowsRequestedBy } }); }, - setAllowsCardSortingByNumber(allowsCardSortingByNumber) { - return { $set: { allowsCardSortingByNumber } }; + async setAllowsCardSortingByNumber(allowsCardSortingByNumber) { + return await Boards.updateAsync(this._id, { $set: { allowsCardSortingByNumber } }); }, - setAllowsShowLists(allowsShowLists) { - return { $set: { allowsShowLists } }; + async setAllowsShowLists(allowsShowLists) { + return await Boards.updateAsync(this._id, { $set: { allowsShowLists } }); }, - - setAllowsAttachments(allowsAttachments) { - return { $set: { allowsAttachments } }; + async setAllowsAttachments(allowsAttachments) { + return await Boards.updateAsync(this._id, { $set: { allowsAttachments } }); }, - setAllowsLabels(allowsLabels) { - return { $set: { allowsLabels } }; + async setAllowsLabels(allowsLabels) { + return await Boards.updateAsync(this._id, { $set: { allowsLabels } }); }, - setAllowsComments(allowsComments) { - return { $set: { allowsComments } }; + async setAllowsComments(allowsComments) { + return await Boards.updateAsync(this._id, { $set: { allowsComments } }); }, - setAllowsDescriptionTitle(allowsDescriptionTitle) { - return { $set: { allowsDescriptionTitle } }; + async setAllowsDescriptionTitle(allowsDescriptionTitle) { + return await Boards.updateAsync(this._id, { $set: { allowsDescriptionTitle } }); }, - setAllowsCardNumber(allowsCardNumber) { - return { $set: { allowsCardNumber } }; + async setAllowsCardNumber(allowsCardNumber) { + return await Boards.updateAsync(this._id, { $set: { allowsCardNumber } }); }, - setAllowsDescriptionText(allowsDescriptionText) { - return { $set: { allowsDescriptionText } }; + async setAllowsDescriptionText(allowsDescriptionText) { + return await Boards.updateAsync(this._id, { $set: { allowsDescriptionText } }); }, - setallowsDescriptionTextOnMinicard(allowsDescriptionTextOnMinicard) { - return { $set: { allowsDescriptionTextOnMinicard } }; + async setallowsDescriptionTextOnMinicard(allowsDescriptionTextOnMinicard) { + return await Boards.updateAsync(this._id, { $set: { allowsDescriptionTextOnMinicard } }); }, - setallowsCoverAttachmentOnMinicard(allowsCoverAttachmentOnMinicard) { - return { $set: { allowsCoverAttachmentOnMinicard } }; + async setallowsCoverAttachmentOnMinicard(allowsCoverAttachmentOnMinicard) { + return await Boards.updateAsync(this._id, { $set: { allowsCoverAttachmentOnMinicard } }); }, - setallowsBadgeAttachmentOnMinicard(allowsBadgeAttachmentOnMinicard) { - return { $set: { allowsBadgeAttachmentOnMinicard } }; + async setallowsBadgeAttachmentOnMinicard(allowsBadgeAttachmentOnMinicard) { + return await Boards.updateAsync(this._id, { $set: { allowsBadgeAttachmentOnMinicard } }); }, - setallowsCardSortingByNumberOnMinicard(allowsCardSortingByNumberOnMinicard) { - return { $set: { allowsCardSortingByNumberOnMinicard } }; + async setallowsCardSortingByNumberOnMinicard(allowsCardSortingByNumberOnMinicard) { + return await Boards.updateAsync(this._id, { $set: { allowsCardSortingByNumberOnMinicard } }); }, - setAllowsActivities(allowsActivities) { - return { $set: { allowsActivities } }; + async setAllowsActivities(allowsActivities) { + return await Boards.updateAsync(this._id, { $set: { allowsActivities } }); }, - setAllowsReceivedDate(allowsReceivedDate) { - return { $set: { allowsReceivedDate } }; + async setAllowsReceivedDate(allowsReceivedDate) { + return await Boards.updateAsync(this._id, { $set: { allowsReceivedDate } }); }, - setAllowsCardCounterList(allowsCardCounterList) { - return { $set: { allowsCardCounterList } }; + async setAllowsCardCounterList(allowsCardCounterList) { + return await Boards.updateAsync(this._id, { $set: { allowsCardCounterList } }); }, - setAllowsBoardMemberList(allowsBoardMemberList) { - return { $set: { allowsBoardMemberList } }; + async setAllowsBoardMemberList(allowsBoardMemberList) { + return await Boards.updateAsync(this._id, { $set: { allowsBoardMemberList } }); }, - setAllowsStartDate(allowsStartDate) { - return { $set: { allowsStartDate } }; + async setAllowsStartDate(allowsStartDate) { + return await Boards.updateAsync(this._id, { $set: { allowsStartDate } }); }, - setAllowsEndDate(allowsEndDate) { - return { $set: { allowsEndDate } }; + async setAllowsEndDate(allowsEndDate) { + return await Boards.updateAsync(this._id, { $set: { allowsEndDate } }); }, - setAllowsDueDate(allowsDueDate) { - return { $set: { allowsDueDate } }; + async setAllowsDueDate(allowsDueDate) { + return await Boards.updateAsync(this._id, { $set: { allowsDueDate } }); }, - setSubtasksDefaultBoardId(subtasksDefaultBoardId) { - return { $set: { subtasksDefaultBoardId } }; + async setSubtasksDefaultBoardId(subtasksDefaultBoardId) { + return await Boards.updateAsync(this._id, { $set: { subtasksDefaultBoardId } }); }, - setSubtasksDefaultListId(subtasksDefaultListId) { - return { $set: { subtasksDefaultListId } }; + async setSubtasksDefaultListId(subtasksDefaultListId) { + return await Boards.updateAsync(this._id, { $set: { subtasksDefaultListId } }); }, - setPresentParentTask(presentParentTask) { - return { $set: { presentParentTask } }; + async setPresentParentTask(presentParentTask) { + return await Boards.updateAsync(this._id, { $set: { presentParentTask } }); }, - move(sortIndex) { - return { $set: { sort: sortIndex } }; + async move(sortIndex) { + return await Boards.updateAsync(this._id, { $set: { sort: sortIndex } }); }, - toggleShowActivities() { - return { $set: { showActivities: !this.showActivities } }; + async toggleShowActivities() { + return await Boards.updateAsync(this._id, { $set: { showActivities: !this.showActivities } }); }, }); @@ -1909,14 +1890,14 @@ if (Meteor.isServer) { check(boardId, String); return ReactiveCache.getBoard(boardId, {}, { backgroundImageUrl: 1 }); }, - quitBoard(boardId) { + async quitBoard(boardId) { check(boardId, String); const board = ReactiveCache.getBoard(boardId); if (board) { const userId = Meteor.userId(); const index = board.memberIndex(userId); if (index >= 0) { - board.removeMember(userId); + await board.removeMember(userId); return true; } else throw new Meteor.Error('error-board-notAMember'); } else throw new Meteor.Error('error-board-doesNotExist'); @@ -1993,14 +1974,14 @@ if (Meteor.isServer) { }); Meteor.methods({ - archiveBoard(boardId) { + async archiveBoard(boardId) { check(boardId, String); const board = ReactiveCache.getBoard(boardId); if (board) { const userId = Meteor.userId(); const index = board.memberIndex(userId); if (index >= 0) { - board.archive(); + await board.archive(); return true; } else throw new Meteor.Error('error-board-notAMember'); } else throw new Meteor.Error('error-board-doesNotExist'); @@ -2159,7 +2140,7 @@ if (Meteor.isServer) { } if (modifier.$set) { const boardId = doc._id; - foreachRemovedMember(doc, modifier.$set, memberId => { + foreachRemovedMember(doc, modifier.$set, async memberId => { Cards.update( { boardId }, { @@ -2182,7 +2163,7 @@ if (Meteor.isServer) { ); const board = Boards._transform(doc); - board.setWatcher(memberId, false); + await board.setWatcher(memberId, false); // Remove board from users starred list if (!board.isPublic()) { @@ -2589,7 +2570,7 @@ JsonRoutes.add('POST', '/api/boards/:boardId/copy', function(req, res) { * @param {boolean} isReadOnly ReadOnly capability * @param {boolean} isReadAssignedOnly ReadAssignedOnly capability */ - JsonRoutes.add('POST', '/api/boards/:boardId/members/:memberId', function( + JsonRoutes.add('POST', '/api/boards/:boardId/members/:memberId', async function( req, res, ) { @@ -2606,7 +2587,7 @@ JsonRoutes.add('POST', '/api/boards/:boardId/copy', function(req, res) { return data; } } - const query = board.setMemberPermission( + const query = await board.setMemberPermission( memberId, isTrue(isAdmin), isTrue(isNoComments), diff --git a/models/cards.js b/models/cards.js index 66a3e3fac..f950f58cf 100644 --- a/models/cards.js +++ b/models/cards.js @@ -572,15 +572,17 @@ Cards.helpers({ }); }, - mapCustomFieldsToBoard(boardId) { + async mapCustomFieldsToBoard(boardId) { // Map custom fields to new board - return this.customFields.map(cf => { + const result = []; + for (const cf of this.customFields) { const oldCf = ReactiveCache.getCustomField(cf._id); // Check if oldCf is undefined or null if (!oldCf) { //console.error(`Custom field with ID ${cf._id} not found.`); - return cf; // Skip this field if oldCf is not found + result.push(cf); // Skip this field if oldCf is not found + continue; } const newCf = ReactiveCache.getCustomField({ @@ -592,11 +594,12 @@ Cards.helpers({ if (newCf) { cf._id = newCf._id; } else if (!_.contains(oldCf.boardIds, boardId)) { - oldCf.addBoard(boardId); + await oldCf.addBoard(boardId); } - return cf; - }); + result.push(cf); + } + return result; }, @@ -1203,11 +1206,11 @@ Cards.helpers({ } }, - assignMember(memberId) { + async assignMember(memberId) { let ret; if (this.isLinkedBoard()) { const board = ReactiveCache.getBoard(this.linkedId); - ret = board.addMember(memberId); + ret = await board.addMember(memberId); } else { ret = Cards.update( { _id: this.getRealId() }, @@ -1234,7 +1237,7 @@ Cards.helpers({ } }, - unassignMember(memberId) { + async unassignMember(memberId) { if (this.isLinkedCard()) { return Cards.update( { _id: this.linkedId }, @@ -1242,7 +1245,7 @@ Cards.helpers({ ); } else if (this.isLinkedBoard()) { const board = ReactiveCache.getBoard(this.linkedId); - return board.removeMember(memberId); + return await board.removeMember(memberId); } else { return Cards.update({ _id: this._id }, { $pull: { members: memberId } }); } @@ -1991,52 +1994,41 @@ Cards.helpers({ } return pokerWinnersListMap[0].pokerCard; }, -}); -Cards.mutations({ - applyToChildren(funct) { - ReactiveCache.getCards({ - parentId: this._id, - }).forEach(card => { - funct(card); + async applyToChildren(funct) { + const cards = ReactiveCache.getCards({ parentId: this._id }); + for (const card of cards) { + await funct(card); + } + }, + + async archive() { + await this.applyToChildren(async card => { + await card.archive(); + }); + return await Cards.updateAsync(this._id, { + $set: { archived: true, archivedAt: new Date() }, }); }, - archive() { - this.applyToChildren(card => { - return card.archive(); + async restore() { + await this.applyToChildren(async card => { + await card.restore(); + }); + return await Cards.updateAsync(this._id, { + $set: { archived: false }, }); - return { - $set: { - archived: true, - archivedAt: new Date(), - }, - }; }, - restore() { - this.applyToChildren(card => { - return card.restore(); - }); - return { - $set: { - archived: false, - }, - }; - }, - - moveToEndOfList({ listId, swimlaneId } = {}) { + async moveToEndOfList({ listId, swimlaneId } = {}) { swimlaneId = swimlaneId || this.swimlaneId; const boardId = this.boardId; let sortIndex = 0; - // This should never happen, but there was a bug that was fixed in commit - // ea0239538a68e225c867411a4f3e0d27c158383. if (!swimlaneId) { const board = ReactiveCache.getBoard(boardId); swimlaneId = board.getDefaultSwimline()._id; } - // Move the minicard to the end of the target list let parentElementDom = $(`#swimlane-${swimlaneId}`).get(0); if (!parentElementDom) parentElementDom = $(':root'); @@ -2045,7 +2037,7 @@ Cards.mutations({ .get(0); if (lastCardDom) sortIndex = Utils.calculateIndex(lastCardDom, null).base; - return this.moveOptionalArgs({ + return await this.moveOptionalArgs({ boardId, swimlaneId, listId, @@ -2053,22 +2045,19 @@ Cards.mutations({ }); }, - moveOptionalArgs({ boardId, swimlaneId, listId, sort } = {}) { + async moveOptionalArgs({ boardId, swimlaneId, listId, sort } = {}) { boardId = boardId || this.boardId; swimlaneId = swimlaneId || this.swimlaneId; - // This should never happen, but there was a bug that was fixed in commit - // ea0239538a68e225c867411a4f3e0d27c158383. if (!swimlaneId) { const board = ReactiveCache.getBoard(boardId); swimlaneId = board.getDefaultSwimline()._id; } listId = listId || this.listId; if (sort === undefined || sort === null) sort = this.sort; - return this.move(boardId, swimlaneId, listId, sort); + return await this.move(boardId, swimlaneId, listId, sort); }, - move(boardId, swimlaneId, listId, sort = null) { - // Capture previous state for history tracking + async move(boardId, swimlaneId, listId, sort = null) { const previousState = { boardId: this.boardId, swimlaneId: this.swimlaneId, @@ -2076,20 +2065,13 @@ Cards.mutations({ sort: this.sort, }; - const mutatedFields = { - boardId, - swimlaneId, - listId, - }; + const mutatedFields = { boardId, swimlaneId, listId }; if (sort !== null) { mutatedFields.sort = sort; } - // we must only copy the labels and custom fields if the target board - // differs from the source board if (this.boardId !== boardId) { - // Get label names const oldBoard = ReactiveCache.getBoard(this.boardId); const oldBoardLabels = oldBoard.labels; const oldCardLabels = _.pluck( @@ -2108,7 +2090,6 @@ Cards.mutations({ '_id', ); - // assign the new card number from the target board const newCardNumber = newBoard.getNextCardNumber(); Object.assign(mutatedFields, { @@ -2119,11 +2100,8 @@ Cards.mutations({ mutatedFields.customFields = this.mapCustomFieldsToBoard(newBoard._id); } - Cards.update(this._id, { - $set: mutatedFields, - }); + await Cards.updateAsync(this._id, { $set: mutatedFields }); - // Track position change in user history (server-side only) if (Meteor.isServer && Meteor.userId() && typeof UserPositionHistory !== 'undefined') { try { UserPositionHistory.trackChange({ @@ -2145,7 +2123,6 @@ Cards.mutations({ } } - // Ensure attachments follow the card to its new board/list/swimlane if (Meteor.isServer) { const updateMeta = {}; if (mutatedFields.boardId !== undefined) updateMeta['meta.boardId'] = mutatedFields.boardId; @@ -2154,293 +2131,159 @@ Cards.mutations({ if (Object.keys(updateMeta).length > 0) { try { - Attachments.collection.update( + await Attachments.collection.updateAsync( { 'meta.cardId': this._id }, { $set: updateMeta }, { multi: true }, ); } catch (err) { - // Do not block the move if attachment update fails - // eslint-disable-next-line no-console console.error('Failed to update attachments metadata after moving card', this._id, err); } } } }, - addLabel(labelId) { + async addLabel(labelId) { this.labelIds.push(labelId); - return { - $addToSet: { - labelIds: labelId, - }, - }; + return await Cards.updateAsync(this._id, { $addToSet: { labelIds: labelId } }); }, - removeLabel(labelId) { + async removeLabel(labelId) { this.labelIds = _.without(this.labelIds, labelId); - return { - $pull: { - labelIds: labelId, - }, - }; + return await Cards.updateAsync(this._id, { $pull: { labelIds: labelId } }); }, - toggleLabel(labelId) { + async toggleLabel(labelId) { if (this.labelIds && this.labelIds.indexOf(labelId) > -1) { - return this.removeLabel(labelId); + return await this.removeLabel(labelId); } else { - return this.addLabel(labelId); + return await this.addLabel(labelId); } }, - setColor(newColor) { + async setColor(newColor) { if (newColor === 'white') { newColor = null; } - return { - $set: { - color: newColor, - }, - }; + return await Cards.updateAsync(this._id, { $set: { color: newColor } }); }, - assignMember(memberId) { - return { - $addToSet: { - members: memberId, - }, - }; + async assignMember(memberId) { + return await Cards.updateAsync(this._id, { $addToSet: { members: memberId } }); }, - assignAssignee(assigneeId) { - // If there is not any assignee, allow one assignee, not more. - /* - if (this.getAssignees().length === 0) { - return { - $addToSet: { - assignees: assigneeId, - }, - }; - */ - // Allow more that one assignee: - // https://github.com/wekan/wekan/issues/3302 - return { - $addToSet: { - assignees: assigneeId, - }, - }; - //} else { - // return false, - //} + async assignAssignee(assigneeId) { + return await Cards.updateAsync(this._id, { $addToSet: { assignees: assigneeId } }); }, - unassignMember(memberId) { - return { - $pull: { - members: memberId, - }, - }; + async unassignMember(memberId) { + return await Cards.updateAsync(this._id, { $pull: { members: memberId } }); }, - unassignAssignee(assigneeId) { - return { - $pull: { - assignees: assigneeId, - }, - }; + async unassignAssignee(assigneeId) { + return await Cards.updateAsync(this._id, { $pull: { assignees: assigneeId } }); }, - toggleMember(memberId) { + async toggleMember(memberId) { if (this.members && this.members.indexOf(memberId) > -1) { - return this.unassignMember(memberId); + return await this.unassignMember(memberId); } else { - return this.assignMember(memberId); + return await this.assignMember(memberId); } }, - toggleAssignee(assigneeId) { + async toggleAssignee(assigneeId) { if (this.assignees && this.assignees.indexOf(assigneeId) > -1) { - return this.unassignAssignee(assigneeId); + return await this.unassignAssignee(assigneeId); } else { - return this.assignAssignee(assigneeId); + return await this.assignAssignee(assigneeId); } }, - assignCustomField(customFieldId) { - return { - $addToSet: { - customFields: { - _id: customFieldId, - value: null, - }, - }, - }; + async assignCustomField(customFieldId) { + return await Cards.updateAsync(this._id, { + $addToSet: { customFields: { _id: customFieldId, value: null } }, + }); }, - unassignCustomField(customFieldId) { - return { - $pull: { - customFields: { - _id: customFieldId, - }, - }, - }; + async unassignCustomField(customFieldId) { + return await Cards.updateAsync(this._id, { + $pull: { customFields: { _id: customFieldId } }, + }); }, - toggleCustomField(customFieldId) { + async toggleCustomField(customFieldId) { if (this.customFields && this.customFieldIndex(customFieldId) > -1) { - return this.unassignCustomField(customFieldId); + return await this.unassignCustomField(customFieldId); } else { - return this.assignCustomField(customFieldId); + return await this.assignCustomField(customFieldId); } }, - toggleShowActivities() { - return { - $set: { - showActivities: !this.showActivities, - } - }; + async toggleShowActivities() { + return await Cards.updateAsync(this._id, { + $set: { showActivities: !this.showActivities }, + }); }, - toggleShowChecklistAtMinicard() { - return { - $set: { - showChecklistAtMinicard: !this.showChecklistAtMinicard, - } - }; + async toggleShowChecklistAtMinicard() { + return await Cards.updateAsync(this._id, { + $set: { showChecklistAtMinicard: !this.showChecklistAtMinicard }, + }); }, - setCustomField(customFieldId, value) { - // todo + async setCustomField(customFieldId, value) { const index = this.customFieldIndex(customFieldId); if (index > -1) { - const update = { - $set: {}, - }; + const update = { $set: {} }; update.$set[`customFields.${index}.value`] = value; - return update; + return await Cards.updateAsync(this._id, update); } - // TODO - // Ignatz 18.05.2018: Return null to silence ESLint. No Idea if that is correct return null; }, - setCover(coverId) { - return { - $set: { - coverId, - }, - }; + async setCover(coverId) { + return await Cards.updateAsync(this._id, { $set: { coverId } }); }, - unsetCover() { - return { - $unset: { - coverId: '', - }, - }; + async unsetCover() { + return await Cards.updateAsync(this._id, { $unset: { coverId: '' } }); }, - //setReceived(receivedAt) { - // return { - // $set: { - // receivedAt, - // }, - // }; - //}, - - unsetReceived() { - return { - $unset: { - receivedAt: '', - }, - }; + async unsetReceived() { + return await Cards.updateAsync(this._id, { $unset: { receivedAt: '' } }); }, - //setStart(startAt) { - // return { - // $set: { - // startAt, - // }, - // }; - //}, - - unsetStart() { - return { - $unset: { - startAt: '', - }, - }; + async unsetStart() { + return await Cards.updateAsync(this._id, { $unset: { startAt: '' } }); }, - //setDue(dueAt) { - // return { - // $set: { - // dueAt, - // }, - // }; - //}, - - unsetDue() { - return { - $unset: { - dueAt: '', - }, - }; + async unsetDue() { + return await Cards.updateAsync(this._id, { $unset: { dueAt: '' } }); }, - //setEnd(endAt) { - // return { - // $set: { - // endAt, - // }, - // }; - //}, - - unsetEnd() { - return { - $unset: { - endAt: '', - }, - }; + async unsetEnd() { + return await Cards.updateAsync(this._id, { $unset: { endAt: '' } }); }, - setOvertime(isOvertime) { - return { - $set: { - isOvertime, - }, - }; + async setOvertime(isOvertime) { + return await Cards.updateAsync(this._id, { $set: { isOvertime } }); }, - setSpentTime(spentTime) { - return { - $set: { - spentTime, - }, - }; + async setSpentTime(spentTime) { + return await Cards.updateAsync(this._id, { $set: { spentTime } }); }, - unsetSpentTime() { - return { - $unset: { - spentTime: '', - isOvertime: false, - }, - }; + async unsetSpentTime() { + return await Cards.updateAsync(this._id, { $unset: { spentTime: '', isOvertime: false } }); }, - setParentId(parentId) { - return { - $set: { - parentId, - }, - }; + async setParentId(parentId) { + return await Cards.updateAsync(this._id, { $set: { parentId } }); }, - setVoteQuestion(question, publicVote, allowNonBoardMembers) { - return { + + async setVoteQuestion(question, publicVote, allowNonBoardMembers) { + return await Cards.updateAsync(this._id, { $set: { vote: { question, @@ -2450,61 +2293,42 @@ Cards.mutations({ negative: [], }, }, - }; + }); }, - unsetVote() { - return { - $unset: { - vote: '', - }, - }; + + async unsetVote() { + return await Cards.updateAsync(this._id, { $unset: { vote: '' } }); }, - setVoteEnd(end) { - return { - $set: { 'vote.end': end }, - }; + + async setVoteEnd(end) { + return await Cards.updateAsync(this._id, { $set: { 'vote.end': end } }); }, - unsetVoteEnd() { - return { - $unset: { 'vote.end': '' }, - }; + + async unsetVoteEnd() { + return await Cards.updateAsync(this._id, { $unset: { 'vote.end': '' } }); }, - setVote(userId, forIt) { + + async setVote(userId, forIt) { switch (forIt) { case true: - // vote for it - return { - $pull: { - 'vote.negative': userId, - }, - $addToSet: { - 'vote.positive': userId, - }, - }; + return await Cards.updateAsync(this._id, { + $pull: { 'vote.negative': userId }, + $addToSet: { 'vote.positive': userId }, + }); case false: - // vote against - return { - $pull: { - 'vote.positive': userId, - }, - $addToSet: { - 'vote.negative': userId, - }, - }; - + return await Cards.updateAsync(this._id, { + $pull: { 'vote.positive': userId }, + $addToSet: { 'vote.negative': userId }, + }); default: - // Remove votes - return { - $pull: { - 'vote.positive': userId, - 'vote.negative': userId, - }, - }; + return await Cards.updateAsync(this._id, { + $pull: { 'vote.positive': userId, 'vote.negative': userId }, + }); } }, - setPokerQuestion(question, allowNonBoardMembers) { - return { + async setPokerQuestion(question, allowNonBoardMembers) { + return await Cards.updateAsync(this._id, { $set: { poker: { question, @@ -2521,246 +2345,47 @@ Cards.mutations({ unsure: [], }, }, - }; + }); }, - setPokerEstimation(estimation) { - return { - $set: { 'poker.estimation': estimation }, - }; + + async setPokerEstimation(estimation) { + return await Cards.updateAsync(this._id, { $set: { 'poker.estimation': estimation } }); }, - unsetPokerEstimation() { - return { - $unset: { 'poker.estimation': '' }, - }; + + async unsetPokerEstimation() { + return await Cards.updateAsync(this._id, { $unset: { 'poker.estimation': '' } }); }, - unsetPoker() { - return { - $unset: { - poker: '', - }, - }; + + async unsetPoker() { + return await Cards.updateAsync(this._id, { $unset: { poker: '' } }); }, - setPokerEnd(end) { - return { - $set: { 'poker.end': end }, - }; + + async setPokerEnd(end) { + return await Cards.updateAsync(this._id, { $set: { 'poker.end': end } }); }, - unsetPokerEnd() { - return { - $unset: { 'poker.end': '' }, - }; + + async unsetPokerEnd() { + return await Cards.updateAsync(this._id, { $unset: { 'poker.end': '' } }); }, - setPoker(userId, state) { - switch (state) { - case 'one': - // poker one - return { - $pull: { - 'poker.two': userId, - 'poker.three': userId, - 'poker.five': userId, - 'poker.eight': userId, - 'poker.thirteen': userId, - 'poker.twenty': userId, - 'poker.forty': userId, - 'poker.oneHundred': userId, - 'poker.unsure': userId, - }, - $addToSet: { - 'poker.one': userId, - }, - }; - case 'two': - // poker two - return { - $pull: { - 'poker.one': userId, - 'poker.three': userId, - 'poker.five': userId, - 'poker.eight': userId, - 'poker.thirteen': userId, - 'poker.twenty': userId, - 'poker.forty': userId, - 'poker.oneHundred': userId, - 'poker.unsure': userId, - }, - $addToSet: { - 'poker.two': userId, - }, - }; - case 'three': - // poker three - return { - $pull: { - 'poker.one': userId, - 'poker.two': userId, - 'poker.five': userId, - 'poker.eight': userId, - 'poker.thirteen': userId, - 'poker.twenty': userId, - 'poker.forty': userId, - 'poker.oneHundred': userId, - 'poker.unsure': userId, - }, - $addToSet: { - 'poker.three': userId, - }, - }; + async setPoker(userId, state) { + const pokerFields = ['one', 'two', 'three', 'five', 'eight', 'thirteen', 'twenty', 'forty', 'oneHundred', 'unsure']; + const pullFields = {}; + pokerFields.forEach(f => { pullFields[`poker.${f}`] = userId; }); - case 'five': - // poker five - return { - $pull: { - 'poker.one': userId, - 'poker.two': userId, - 'poker.three': userId, - 'poker.eight': userId, - 'poker.thirteen': userId, - 'poker.twenty': userId, - 'poker.forty': userId, - 'poker.oneHundred': userId, - 'poker.unsure': userId, - }, - $addToSet: { - 'poker.five': userId, - }, - }; - - case 'eight': - // poker eight - return { - $pull: { - 'poker.one': userId, - 'poker.two': userId, - 'poker.three': userId, - 'poker.five': userId, - 'poker.thirteen': userId, - 'poker.twenty': userId, - 'poker.forty': userId, - 'poker.oneHundred': userId, - 'poker.unsure': userId, - }, - $addToSet: { - 'poker.eight': userId, - }, - }; - - case 'thirteen': - // poker thirteen - return { - $pull: { - 'poker.one': userId, - 'poker.two': userId, - 'poker.three': userId, - 'poker.five': userId, - 'poker.eight': userId, - 'poker.twenty': userId, - 'poker.forty': userId, - 'poker.oneHundred': userId, - 'poker.unsure': userId, - }, - $addToSet: { - 'poker.thirteen': userId, - }, - }; - - case 'twenty': - // poker twenty - return { - $pull: { - 'poker.one': userId, - 'poker.two': userId, - 'poker.three': userId, - 'poker.five': userId, - 'poker.eight': userId, - 'poker.thirteen': userId, - 'poker.forty': userId, - 'poker.oneHundred': userId, - 'poker.unsure': userId, - }, - $addToSet: { - 'poker.twenty': userId, - }, - }; - - case 'forty': - // poker forty - return { - $pull: { - 'poker.one': userId, - 'poker.two': userId, - 'poker.three': userId, - 'poker.five': userId, - 'poker.eight': userId, - 'poker.thirteen': userId, - 'poker.twenty': userId, - 'poker.oneHundred': userId, - 'poker.unsure': userId, - }, - $addToSet: { - 'poker.forty': userId, - }, - }; - - case 'oneHundred': - // poker one hundred - return { - $pull: { - 'poker.one': userId, - 'poker.two': userId, - 'poker.three': userId, - 'poker.five': userId, - 'poker.eight': userId, - 'poker.thirteen': userId, - 'poker.twenty': userId, - 'poker.forty': userId, - 'poker.unsure': userId, - }, - $addToSet: { - 'poker.oneHundred': userId, - }, - }; - - case 'unsure': - // poker unsure - return { - $pull: { - 'poker.one': userId, - 'poker.two': userId, - 'poker.three': userId, - 'poker.five': userId, - 'poker.eight': userId, - 'poker.thirteen': userId, - 'poker.twenty': userId, - 'poker.forty': userId, - 'poker.oneHundred': userId, - }, - $addToSet: { - 'poker.unsure': userId, - }, - }; - - default: - // Remove pokers - return { - $pull: { - 'poker.one': userId, - 'poker.two': userId, - 'poker.three': userId, - 'poker.five': userId, - 'poker.eight': userId, - 'poker.thirteen': userId, - 'poker.twenty': userId, - 'poker.forty': userId, - 'poker.oneHundred': userId, - 'poker.unsure': userId, - }, - }; + if (pokerFields.includes(state)) { + delete pullFields[`poker.${state}`]; + return await Cards.updateAsync(this._id, { + $pull: pullFields, + $addToSet: { [`poker.${state}`]: userId }, + }); + } else { + return await Cards.updateAsync(this._id, { $pull: pullFields }); } }, - replayPoker() { - return { + + async replayPoker() { + return await Cards.updateAsync(this._id, { $set: { 'poker.one': [], 'poker.two': [], @@ -2773,7 +2398,7 @@ Cards.mutations({ 'poker.oneHundred': [], 'poker.unsure': [], }, - }; + }); }, }); @@ -4544,7 +4169,7 @@ JsonRoutes.add('GET', '/api/boards/:boardId/cards_count', function( JsonRoutes.add( 'POST', '/api/boards/:boardId/lists/:listId/cards/:cardId/archive', - function(req, res) { + async function(req, res) { const paramBoardId = req.params.boardId; const paramCardId = req.params.cardId; const paramListId = req.params.listId; @@ -4558,7 +4183,7 @@ JsonRoutes.add('GET', '/api/boards/:boardId/cards_count', function( if (!card) { throw new Meteor.Error(404, 'Card not found'); } - card.archive(); + await card.archive(); JsonRoutes.sendResult(res, { code: 200, data: { @@ -4583,7 +4208,7 @@ JsonRoutes.add('GET', '/api/boards/:boardId/cards_count', function( JsonRoutes.add( 'POST', '/api/boards/:boardId/lists/:listId/cards/:cardId/unarchive', - function(req, res) { + async function(req, res) { const paramBoardId = req.params.boardId; const paramCardId = req.params.cardId; const paramListId = req.params.listId; @@ -4597,7 +4222,7 @@ JsonRoutes.add('GET', '/api/boards/:boardId/cards_count', function( if (!card) { throw new Meteor.Error(404, 'Card not found'); } - card.restore(); + await card.restore(); JsonRoutes.sendResult(res, { code: 200, data: { diff --git a/models/checklistItems.js b/models/checklistItems.js index db2aa55bd..0d4c23761 100644 --- a/models/checklistItems.js +++ b/models/checklistItems.js @@ -90,29 +90,24 @@ ChecklistItems.before.insert((userId, doc) => { } }); -// Mutations -ChecklistItems.mutations({ - setTitle(title) { - return { $set: { title } }; +ChecklistItems.helpers({ + async setTitle(title) { + return await ChecklistItems.updateAsync(this._id, { $set: { title } }); }, - check() { - return { $set: { isFinished: true } }; + async check() { + return await ChecklistItems.updateAsync(this._id, { $set: { isFinished: true } }); }, - uncheck() { - return { $set: { isFinished: false } }; + async uncheck() { + return await ChecklistItems.updateAsync(this._id, { $set: { isFinished: false } }); }, - toggleItem() { - return { $set: { isFinished: !this.isFinished } }; + async toggleItem() { + return await ChecklistItems.updateAsync(this._id, { $set: { isFinished: !this.isFinished } }); }, - move(checklistId, sortIndex) { + async move(checklistId, sortIndex) { const cardId = ReactiveCache.getChecklist(checklistId).cardId; - const mutatedFields = { - cardId, - checklistId, - sort: sortIndex, - }; - - return { $set: mutatedFields }; + return await ChecklistItems.updateAsync(this._id, { + $set: { cardId, checklistId, sort: sortIndex }, + }); }, }); diff --git a/models/checklists.js b/models/checklists.js index 606e58f3f..e96ae6bcf 100644 --- a/models/checklists.js +++ b/models/checklists.js @@ -150,22 +150,49 @@ Checklists.helpers({ } return ret; }, - checkAllItems() { + async checkAllItems() { const checkItems = ReactiveCache.getChecklistItems({ checklistId: this._id }); - checkItems.forEach(function(item) { - item.check(); - }); + for (const item of checkItems) { + await item.check(); + } }, - uncheckAllItems() { + async uncheckAllItems() { const checkItems = ReactiveCache.getChecklistItems({ checklistId: this._id }); - checkItems.forEach(function(item) { - item.uncheck(); - }); + for (const item of checkItems) { + await item.uncheck(); + } }, itemIndex(itemId) { const items = ReactiveCache.getChecklist({ _id: this._id }).items; return _.pluck(items, '_id').indexOf(itemId); }, + + async setTitle(title) { + return await Checklists.updateAsync(this._id, { $set: { title } }); + }, + /** move the checklist to another card + * @param newCardId move the checklist to this cardId + */ + async move(newCardId) { + // Note: Activities and ChecklistItems updates are now handled server-side + // in the moveChecklist Meteor method to avoid client-side permission issues + return await Checklists.updateAsync(this._id, { $set: { cardId: newCardId } }); + }, + async toggleHideCheckedChecklistItems() { + return await Checklists.updateAsync(this._id, { + $set: { hideCheckedChecklistItems: !this.hideCheckedChecklistItems }, + }); + }, + async toggleHideAllChecklistItems() { + return await Checklists.updateAsync(this._id, { + $set: { hideAllChecklistItems: !this.hideAllChecklistItems }, + }); + }, + async toggleShowChecklistAtMinicard() { + return await Checklists.updateAsync(this._id, { + $set: { showChecklistAtMinicard: !this.showChecklistAtMinicard }, + }); + }, }); Checklists.allow({ @@ -191,46 +218,6 @@ Checklists.before.insert((userId, doc) => { } }); -Checklists.mutations({ - setTitle(title) { - return { $set: { title } }; - }, - /** move the checklist to another card - * @param newCardId move the checklist to this cardId - */ - move(newCardId) { - // Note: Activities and ChecklistItems updates are now handled server-side - // in the moveChecklist Meteor method to avoid client-side permission issues - - // update the checklist itself - return { - $set: { - cardId: newCardId, - }, - }; - }, - toggleHideCheckedChecklistItems() { - return { - $set: { - hideCheckedChecklistItems: !this.hideCheckedChecklistItems, - } - }; - }, - toggleHideAllChecklistItems() { - return { - $set: { - hideAllChecklistItems: !this.hideAllChecklistItems, - } - }; - }, - toggleShowChecklistAtMinicard() { - return { - $set: { - showChecklistAtMinicard: !this.showChecklistAtMinicard, - } - }; - }, -}); if (Meteor.isServer) { Meteor.methods({ diff --git a/models/csvCreator.js b/models/csvCreator.js index e7d83331b..fd3ee399a 100644 --- a/models/csvCreator.js +++ b/models/csvCreator.js @@ -382,14 +382,14 @@ export class CsvCreator { } } - create(board, currentBoardId) { + async create(board, currentBoardId) { const isSandstorm = Meteor.settings && Meteor.settings.public && Meteor.settings.public.sandstorm; if (isSandstorm && currentBoardId) { const currentBoard = ReactiveCache.getBoard(currentBoardId); - currentBoard.archive(); + await currentBoard.archive(); } this.mapHeadertoCardFieldIndex(board[0]); const boardId = this.createBoard(board); diff --git a/models/customFields.js b/models/customFields.js index 55d4cef98..db8aaa8c2 100644 --- a/models/customFields.js +++ b/models/customFields.js @@ -152,17 +152,14 @@ CustomFields.addToAllCards = cf => { ); }; -CustomFields.mutations({ - addBoard(boardId) { +CustomFields.helpers({ + async addBoard(boardId) { if (boardId) { - return { - $push: { - boardIds: boardId, - }, - }; - } else { - return null; + return await CustomFields.updateAsync(this._id, { + $push: { boardIds: boardId }, + }); } + return null; }, }); diff --git a/models/lists.js b/models/lists.js index 4eb4574f1..1b2307f04 100644 --- a/models/lists.js +++ b/models/lists.js @@ -226,7 +226,7 @@ Lists.helpers({ }); }, - move(boardId, swimlaneId) { + async move(boardId, swimlaneId) { const boardList = ReactiveCache.getList({ boardId, title: this.title, @@ -235,9 +235,9 @@ Lists.helpers({ let listId; if (boardList) { listId = boardList._id; - this.cards().forEach(card => { - card.move(boardId, this._id, boardList._id); - }); + for (const card of this.cards()) { + await card.move(boardId, this._id, boardList._id); + } } else { console.log('list.title:', this.title); console.log('boardList:', boardList); @@ -251,9 +251,9 @@ Lists.helpers({ }); } - this.cards(swimlaneId).forEach(card => { - card.move(boardId, swimlaneId, listId); - }); + for (const card of this.cards(swimlaneId)) { + await card.move(boardId, swimlaneId, listId); + } }, cards(swimlaneId) { @@ -342,61 +342,55 @@ Lists.helpers({ remove() { Lists.remove({ _id: this._id }); }, -}); -Lists.mutations({ - rename(title) { + async rename(title) { // Basic client-side validation - server will handle full sanitization if (typeof title === 'string') { // Basic length check to prevent abuse const sanitizedTitle = title.length > 1000 ? title.substring(0, 1000) : title; - return { $set: { title: sanitizedTitle } }; + return await Lists.updateAsync(this._id, { $set: { title: sanitizedTitle } }); } - return { $set: { title } }; + return await Lists.updateAsync(this._id, { $set: { title } }); }, - star(enable = true) { - return { $set: { starred: !!enable } }; + async star(enable = true) { + return await Lists.updateAsync(this._id, { $set: { starred: !!enable } }); }, - collapse(enable = true) { - return { $set: { collapsed: !!enable } }; + async collapse(enable = true) { + return await Lists.updateAsync(this._id, { $set: { collapsed: !!enable } }); }, - archive() { + async archive() { if (this.isTemplateList()) { - this.cards().forEach(card => { - return card.archive(); - }); + for (const card of this.cards()) { + await card.archive(); + } } - return { $set: { archived: true, archivedAt: new Date() } }; + return await Lists.updateAsync(this._id, { $set: { archived: true, archivedAt: new Date() } }); }, - restore() { + async restore() { if (this.isTemplateList()) { - this.allCards().forEach(card => { - return card.restore(); - }); + for (const card of this.allCards()) { + await card.restore(); + } } - return { $set: { archived: false } }; + return await Lists.updateAsync(this._id, { $set: { archived: false } }); }, - toggleSoftLimit(toggle) { - return { $set: { 'wipLimit.soft': toggle } }; + async toggleSoftLimit(toggle) { + return await Lists.updateAsync(this._id, { $set: { 'wipLimit.soft': toggle } }); }, - toggleWipLimit(toggle) { - return { $set: { 'wipLimit.enabled': toggle } }; + async toggleWipLimit(toggle) { + return await Lists.updateAsync(this._id, { $set: { 'wipLimit.enabled': toggle } }); }, - setWipLimit(limit) { - return { $set: { 'wipLimit.value': limit } }; + async setWipLimit(limit) { + return await Lists.updateAsync(this._id, { $set: { 'wipLimit.value': limit } }); }, - setColor(newColor) { - return { - $set: { - color: newColor, - }, - }; + async setColor(newColor) { + return await Lists.updateAsync(this._id, { $set: { color: newColor } }); }, }); @@ -422,49 +416,49 @@ Lists.archivedListIds = () => { }; Meteor.methods({ - applyWipLimit(listId, limit) { + async applyWipLimit(listId, limit) { check(listId, String); check(limit, Number); - + if (!this.userId) { throw new Meteor.Error('not-authorized', 'You must be logged in.'); } - + const list = ReactiveCache.getList(listId); if (!list) { throw new Meteor.Error('list-not-found', 'List not found'); } - + const board = ReactiveCache.getBoard(list.boardId); if (!board || !board.hasAdmin(this.userId)) { throw new Meteor.Error('not-authorized', 'You must be a board admin to modify WIP limits.'); } - + if (limit === 0) { limit = 1; } - list.setWipLimit(limit); + await list.setWipLimit(limit); }, - enableWipLimit(listId) { + async enableWipLimit(listId) { check(listId, String); - + if (!this.userId) { throw new Meteor.Error('not-authorized', 'You must be logged in.'); } - + const list = ReactiveCache.getList(listId); if (!list) { throw new Meteor.Error('list-not-found', 'List not found'); } - + const board = ReactiveCache.getBoard(list.boardId); if (!board || !board.hasAdmin(this.userId)) { throw new Meteor.Error('not-authorized', 'You must be a board admin to modify WIP limits.'); } - + if (list.getWipLimit('value') === 0) { - list.setWipLimit(1); + await list.setWipLimit(1); } list.toggleWipLimit(!list.getWipLimit('enabled')); }, diff --git a/models/rules.js b/models/rules.js index 38b3c87a5..55417ca49 100644 --- a/models/rules.js +++ b/models/rules.js @@ -50,13 +50,10 @@ Rules.attachSchema( }), ); -Rules.mutations({ - rename(description) { - return { $set: { description } }; - }, -}); - Rules.helpers({ + async rename(description) { + return await Rules.updateAsync(this._id, { $set: { description } }); + }, getAction() { return ReactiveCache.getAction(this.actionId); }, diff --git a/models/swimlanes.js b/models/swimlanes.js index 64dbfe529..94347a62d 100644 --- a/models/swimlanes.js +++ b/models/swimlanes.js @@ -171,8 +171,8 @@ Swimlanes.helpers({ }); }, - move(toBoardId) { - this.lists().forEach(list => { + async move(toBoardId) { + for (const list of this.lists()) { const toList = ReactiveCache.getList({ boardId: toBoardId, title: list.title, @@ -193,13 +193,14 @@ Swimlanes.helpers({ }); } - ReactiveCache.getCards({ + const cards = ReactiveCache.getCards({ listId: list._id, swimlaneId: this._id, - }).forEach(card => { - card.move(toBoardId, this._id, toListId); }); - }); + for (const card of cards) { + await card.move(toBoardId, this._id, toListId); + } + } Swimlanes.update(this._id, { $set: { @@ -317,40 +318,34 @@ Swimlanes.helpers({ remove() { Swimlanes.remove({ _id: this._id }); }, -}); -Swimlanes.mutations({ - rename(title) { - return { $set: { title } }; + async rename(title) { + return await Swimlanes.updateAsync(this._id, { $set: { title } }); }, // NOTE: collapse() removed - collapsed state is per-user only // Use user.setCollapsedSwimlane(boardId, swimlaneId, collapsed) instead - archive() { + async archive() { if (this.isTemplateSwimlane()) { - this.myLists().forEach(list => { - return list.archive(); - }); + for (const list of this.myLists()) { + await list.archive(); + } } - return { $set: { archived: true, archivedAt: new Date() } }; + return await Swimlanes.updateAsync(this._id, { $set: { archived: true, archivedAt: new Date() } }); }, - restore() { + async restore() { if (this.isTemplateSwimlane()) { - this.myLists().forEach(list => { - return list.restore(); - }); + for (const list of this.myLists()) { + await list.restore(); + } } - return { $set: { archived: false } }; + return await Swimlanes.updateAsync(this._id, { $set: { archived: false } }); }, - setColor(newColor) { - return { - $set: { - color: newColor, - }, - }; + async setColor(newColor) { + return await Swimlanes.updateAsync(this._id, { $set: { color: newColor } }); }, }); diff --git a/models/trelloCreator.js b/models/trelloCreator.js index c0400b443..19ae3aba3 100644 --- a/models/trelloCreator.js +++ b/models/trelloCreator.js @@ -767,7 +767,7 @@ export class TrelloCreator { } } - create(board, currentBoardId) { + async create(board, currentBoardId) { // TODO : Make isSandstorm variable global const isSandstorm = Meteor.settings && @@ -775,7 +775,7 @@ export class TrelloCreator { Meteor.settings.public.sandstorm; if (isSandstorm && currentBoardId) { const currentBoard = ReactiveCache.getBoard(currentBoardId); - currentBoard.archive(); + await currentBoard.archive(); } this.parseActions(board.actions); const boardId = this.createBoardAndLabels(board); diff --git a/models/triggers.js b/models/triggers.js index 6983955c6..d9c9390cc 100644 --- a/models/triggers.js +++ b/models/triggers.js @@ -3,16 +3,6 @@ import { Meteor } from 'meteor/meteor'; Triggers = new Mongo.Collection('triggers'); -Triggers.mutations({ - rename(description) { - return { - $set: { - description, - }, - }; - }, -}); - Triggers.before.insert((userId, doc) => { doc.createdAt = new Date(); doc.updatedAt = doc.createdAt; @@ -36,6 +26,12 @@ Triggers.allow({ }); Triggers.helpers({ + async rename(description) { + return await Triggers.updateAsync(this._id, { + $set: { description }, + }); + }, + description() { return this.desc; }, diff --git a/models/users.js b/models/users.js index f61bdb1c0..5c239408a 100644 --- a/models/users.js +++ b/models/users.js @@ -1593,376 +1593,206 @@ Users.helpers({ } return null; }, -}); -Users.mutations({ - /** set the confirmed board id/swimlane id/list id of a board - * @param boardId the current board id - * @param options an object with the confirmed field values - */ - setMoveAndCopyDialogOption(boardId, options) { + async setMoveAndCopyDialogOption(boardId, options) { let currentOptions = this.getMoveAndCopyDialogOptions(); currentOptions[boardId] = options; - return { - $set: { - 'profile.moveAndCopyDialog': currentOptions, - }, - }; + return await Users.updateAsync(this._id, { $set: { 'profile.moveAndCopyDialog': currentOptions } }); }, - /** set the confirmed board id/swimlane id/list id/card id of a board (move checklist) - * @param boardId the current board id - * @param options an object with the confirmed field values - */ - setMoveChecklistDialogOption(boardId, options) { + + async setMoveChecklistDialogOption(boardId, options) { let currentOptions = this.getMoveChecklistDialogOptions(); currentOptions[boardId] = options; - return { - $set: { - 'profile.moveChecklistDialog': currentOptions, - }, - }; + return await Users.updateAsync(this._id, { $set: { 'profile.moveChecklistDialog': currentOptions } }); }, - /** set the confirmed board id/swimlane id/list id/card id of a board (copy checklist) - * @param boardId the current board id - * @param options an object with the confirmed field values - */ - setCopyChecklistDialogOption(boardId, options) { + + async setCopyChecklistDialogOption(boardId, options) { let currentOptions = this.getCopyChecklistDialogOptions(); currentOptions[boardId] = options; - return { - $set: { - 'profile.copyChecklistDialog': currentOptions, - }, - }; + return await Users.updateAsync(this._id, { $set: { 'profile.copyChecklistDialog': currentOptions } }); }, - toggleBoardStar(boardId) { + + async toggleBoardStar(boardId) { const queryKind = this.hasStarred(boardId) ? '$pull' : '$addToSet'; - return { - [queryKind]: { - 'profile.starredBoards': boardId, - }, - }; + return await Users.updateAsync(this._id, { [queryKind]: { 'profile.starredBoards': boardId } }); }, - /** - * Set per-user board sort index for a board - * Stored at profile.boardSortIndex[boardId] = sortIndex (Number) - */ - setBoardSortIndex(boardId, sortIndex) { + + async setBoardSortIndex(boardId, sortIndex) { const mapping = (this.profile && this.profile.boardSortIndex) || {}; mapping[boardId] = sortIndex; - return { - $set: { - 'profile.boardSortIndex': mapping, - }, - }; + return await Users.updateAsync(this._id, { $set: { 'profile.boardSortIndex': mapping } }); }, - toggleAutoWidth(boardId) { + + async toggleAutoWidth(boardId) { const { autoWidthBoards = {} } = this.profile || {}; autoWidthBoards[boardId] = !autoWidthBoards[boardId]; - return { - $set: { - 'profile.autoWidthBoards': autoWidthBoards, - }, - }; + return await Users.updateAsync(this._id, { $set: { 'profile.autoWidthBoards': autoWidthBoards } }); }, - toggleKeyboardShortcuts() { + + async toggleKeyboardShortcuts() { const { keyboardShortcuts = true } = this.profile || {}; - return { - $set: { - 'profile.keyboardShortcuts': !keyboardShortcuts, - }, - }; + return await Users.updateAsync(this._id, { $set: { 'profile.keyboardShortcuts': !keyboardShortcuts } }); }, - toggleVerticalScrollbars() { + + async toggleVerticalScrollbars() { const { verticalScrollbars = true } = this.profile || {}; - return { - $set: { - 'profile.verticalScrollbars': !verticalScrollbars, - }, - }; + return await Users.updateAsync(this._id, { $set: { 'profile.verticalScrollbars': !verticalScrollbars } }); }, - toggleShowWeekOfYear() { + + async toggleShowWeekOfYear() { const { showWeekOfYear = true } = this.profile || {}; - return { - $set: { - 'profile.showWeekOfYear': !showWeekOfYear, - }, - }; + return await Users.updateAsync(this._id, { $set: { 'profile.showWeekOfYear': !showWeekOfYear } }); }, - addInvite(boardId) { - return { - $addToSet: { - 'profile.invitedBoards': boardId, - }, - }; + async addInvite(boardId) { + return await Users.updateAsync(this._id, { $addToSet: { 'profile.invitedBoards': boardId } }); }, - removeInvite(boardId) { - return { - $pull: { - 'profile.invitedBoards': boardId, - }, - }; + async removeInvite(boardId) { + return await Users.updateAsync(this._id, { $pull: { 'profile.invitedBoards': boardId } }); }, - addTag(tag) { - return { - $addToSet: { - 'profile.tags': tag, - }, - }; + async addTag(tag) { + return await Users.updateAsync(this._id, { $addToSet: { 'profile.tags': tag } }); }, - removeTag(tag) { - return { - $pull: { - 'profile.tags': tag, - }, - }; + async removeTag(tag) { + return await Users.updateAsync(this._id, { $pull: { 'profile.tags': tag } }); }, - toggleTag(tag) { - if (this.hasTag(tag)) this.removeTag(tag); - else this.addTag(tag); + async toggleTag(tag) { + if (this.hasTag(tag)) { + return await this.removeTag(tag); + } else { + return await this.addTag(tag); + } }, - setListSortBy(value) { - return { - $set: { - 'profile.listSortBy': value, - }, - }; + async setListSortBy(value) { + return await Users.updateAsync(this._id, { $set: { 'profile.listSortBy': value } }); }, - setName(value) { - return { - $set: { - 'profile.fullname': value, - }, - }; + async setName(value) { + return await Users.updateAsync(this._id, { $set: { 'profile.fullname': value } }); }, - toggleDesktopHandles(value = false) { - return { - $set: { - 'profile.showDesktopDragHandles': !value, - }, - }; + async toggleDesktopHandles(value = false) { + return await Users.updateAsync(this._id, { $set: { 'profile.showDesktopDragHandles': !value } }); }, - toggleFieldsGrid(value = false) { - return { - $set: { - 'profile.customFieldsGrid': !value, - }, - }; + async toggleFieldsGrid(value = false) { + return await Users.updateAsync(this._id, { $set: { 'profile.customFieldsGrid': !value } }); }, - toggleCardMaximized(value = false) { - return { - $set: { - 'profile.cardMaximized': !value, - }, - }; + async toggleCardMaximized(value = false) { + return await Users.updateAsync(this._id, { $set: { 'profile.cardMaximized': !value } }); }, - toggleCardCollapsed(value = false) { - return { - $set: { - 'profile.cardCollapsed': !value, - }, - }; + async toggleCardCollapsed(value = false) { + return await Users.updateAsync(this._id, { $set: { 'profile.cardCollapsed': !value } }); }, - toggleShowActivities(value = false) { - return { - $set: { - 'profile.showActivities': !value, - }, - }; + async toggleShowActivities(value = false) { + return await Users.updateAsync(this._id, { $set: { 'profile.showActivities': !value } }); }, - toggleLabelText(value = false) { - return { - $set: { - 'profile.hiddenMinicardLabelText': !value, - }, - }; - }, - toggleRescueCardDescription(value = false) { - return { - $set: { - 'profile.rescueCardDescription': !value, - }, - }; - }, - toggleGreyIcons(value = false) { - return { - $set: { - 'profile.GreyIcons': !value, - }, - }; + async toggleLabelText(value = false) { + return await Users.updateAsync(this._id, { $set: { 'profile.hiddenMinicardLabelText': !value } }); }, - addNotification(activityId) { - return { - $addToSet: { - 'profile.notifications': { - activity: activityId, - read: null, - }, - }, - }; + async toggleRescueCardDescription(value = false) { + return await Users.updateAsync(this._id, { $set: { 'profile.rescueCardDescription': !value } }); }, - removeNotification(activityId) { - return { - $pull: { - 'profile.notifications': { - activity: activityId, - }, - }, - }; + async toggleGreyIcons(value = false) { + return await Users.updateAsync(this._id, { $set: { 'profile.GreyIcons': !value } }); }, - addEmailBuffer(text) { - return { - $addToSet: { - 'profile.emailBuffer': text, - }, - }; + async addNotification(activityId) { + return await Users.updateAsync(this._id, { + $addToSet: { 'profile.notifications': { activity: activityId, read: null } }, + }); }, - clearEmailBuffer() { - return { - $set: { - 'profile.emailBuffer': [], - }, - }; + async removeNotification(activityId) { + return await Users.updateAsync(this._id, { + $pull: { 'profile.notifications': { activity: activityId } }, + }); }, - setAvatarUrl(avatarUrl) { - return { - $set: { - 'profile.avatarUrl': avatarUrl, - }, - }; + async addEmailBuffer(text) { + return await Users.updateAsync(this._id, { $addToSet: { 'profile.emailBuffer': text } }); }, - setShowCardsCountAt(limit) { - return { - $set: { - 'profile.showCardsCountAt': limit, - }, - }; + async clearEmailBuffer() { + return await Users.updateAsync(this._id, { $set: { 'profile.emailBuffer': [] } }); }, - setStartDayOfWeek(startDay) { - return { - $set: { - 'profile.startDayOfWeek': startDay, - }, - }; + async setAvatarUrl(avatarUrl) { + return await Users.updateAsync(this._id, { $set: { 'profile.avatarUrl': avatarUrl } }); }, - setDateFormat(dateFormat) { - return { - $set: { - 'profile.dateFormat': dateFormat, - }, - }; + async setShowCardsCountAt(limit) { + return await Users.updateAsync(this._id, { $set: { 'profile.showCardsCountAt': limit } }); }, - setBoardView(view) { - return { - $set: { - 'profile.boardView': view, - }, - }; + async setStartDayOfWeek(startDay) { + return await Users.updateAsync(this._id, { $set: { 'profile.startDayOfWeek': startDay } }); }, - setListWidth(boardId, listId, width) { + async setDateFormat(dateFormat) { + return await Users.updateAsync(this._id, { $set: { 'profile.dateFormat': dateFormat } }); + }, + + async setBoardView(view) { + return await Users.updateAsync(this._id, { $set: { 'profile.boardView': view } }); + }, + + async setListWidth(boardId, listId, width) { let currentWidths = this.getListWidths(); - if (!currentWidths[boardId]) { - currentWidths[boardId] = {}; - } + if (!currentWidths[boardId]) currentWidths[boardId] = {}; currentWidths[boardId][listId] = width; - return { - $set: { - 'profile.listWidths': currentWidths, - }, - }; + return await Users.updateAsync(this._id, { $set: { 'profile.listWidths': currentWidths } }); }, - setListConstraint(boardId, listId, constraint) { + async setListConstraint(boardId, listId, constraint) { let currentConstraints = this.getListConstraints(); - if (!currentConstraints[boardId]) { - currentConstraints[boardId] = {}; - } + if (!currentConstraints[boardId]) currentConstraints[boardId] = {}; currentConstraints[boardId][listId] = constraint; - return { - $set: { - 'profile.listConstraints': currentConstraints, - }, - }; + return await Users.updateAsync(this._id, { $set: { 'profile.listConstraints': currentConstraints } }); }, - setSwimlaneHeight(boardId, swimlaneId, height) { + async setSwimlaneHeight(boardId, swimlaneId, height) { let currentHeights = this.getSwimlaneHeights(); - if (!currentHeights[boardId]) { - currentHeights[boardId] = {}; - } + if (!currentHeights[boardId]) currentHeights[boardId] = {}; currentHeights[boardId][swimlaneId] = height; - return { - $set: { - 'profile.swimlaneHeights': currentHeights, - }, - }; + return await Users.updateAsync(this._id, { $set: { 'profile.swimlaneHeights': currentHeights } }); }, - setCollapsedList(boardId, listId, collapsed) { + + async setCollapsedList(boardId, listId, collapsed) { const current = (this.profile && this.profile.collapsedLists) || {}; if (!current[boardId]) current[boardId] = {}; current[boardId][listId] = !!collapsed; - return { - $set: { - 'profile.collapsedLists': current, - }, - }; + return await Users.updateAsync(this._id, { $set: { 'profile.collapsedLists': current } }); }, - setCollapsedSwimlane(boardId, swimlaneId, collapsed) { + + async setCollapsedSwimlane(boardId, swimlaneId, collapsed) { const current = (this.profile && this.profile.collapsedSwimlanes) || {}; if (!current[boardId]) current[boardId] = {}; current[boardId][swimlaneId] = !!collapsed; - return { - $set: { - 'profile.collapsedSwimlanes': current, - }, - }; + return await Users.updateAsync(this._id, { $set: { 'profile.collapsedSwimlanes': current } }); }, - setZoomLevel(level) { - return { - $set: { - 'profile.zoomLevel': level, - }, - }; + async setZoomLevel(level) { + return await Users.updateAsync(this._id, { $set: { 'profile.zoomLevel': level } }); }, - setMobileMode(enabled) { - return { - $set: { - 'profile.mobileMode': enabled, - }, - }; + async setMobileMode(enabled) { + return await Users.updateAsync(this._id, { $set: { 'profile.mobileMode': enabled } }); }, - setCardZoom(level) { - return { - $set: { - 'profile.cardZoom': level, - }, - }; + async setCardZoom(level) { + return await Users.updateAsync(this._id, { $set: { 'profile.cardZoom': level } }); }, }); @@ -3340,7 +3170,7 @@ if (Meteor.isServer) { * @return_type {_id: string, * title: string} */ - JsonRoutes.add('PUT', '/api/users/:userId', function (req, res) { + JsonRoutes.add('PUT', '/api/users/:userId', async function (req, res) { try { Authentication.checkUserId(req.userId); const id = req.params.userId; @@ -3350,7 +3180,7 @@ if (Meteor.isServer) { }); if (data !== undefined) { if (action === 'takeOwnership') { - data = ReactiveCache.getBoards( + const boards = ReactiveCache.getBoards( { 'members.userId': id, 'members.isAdmin': true, @@ -3360,16 +3190,18 @@ if (Meteor.isServer) { sort: 1 /* boards default sorting */, }, }, - ).map(function (board) { + ); + data = []; + for (const board of boards) { if (board.hasMember(req.userId)) { - board.removeMember(req.userId); + await board.removeMember(req.userId); } board.changeOwnership(id, req.userId); - return { + data.push({ _id: board._id, title: board.title, - }; - }); + }); + } } else { if (action === 'disableLogin' && id !== req.userId) { Users.update( diff --git a/models/watchable.js b/models/watchable.js index 7dbacb594..73cb0564c 100644 --- a/models/watchable.js +++ b/models/watchable.js @@ -19,13 +19,13 @@ const simpleWatchable = collection => { findWatcher(userId) { return _.contains(this.watchers, userId); }, - }); - collection.mutations({ - setWatcher(userId, level) { + async setWatcher(userId, level) { // if level undefined or null or false, then remove - if (!level) return { $pull: { watchers: userId } }; - return { $addToSet: { watchers: userId } }; + if (!level) { + return await collection.updateAsync(this._id, { $pull: { watchers: userId } }); + } + return await collection.updateAsync(this._id, { $addToSet: { watchers: userId } }); }, }); }; @@ -66,20 +66,20 @@ const complexWatchable = collection => { const watcher = this.findWatcher(userId); return watcher ? watcher.level : complexWatchDefault; }, - }); - collection.mutations({ - setWatcher(userId, level) { + async setWatcher(userId, level) { // if level undefined or null or false, then remove if (level === complexWatchDefault) level = null; - if (!level) return { $pull: { watchers: { userId } } }; + if (!level) { + return await collection.updateAsync(this._id, { $pull: { watchers: { userId } } }); + } const index = this.watcherIndex(userId); - if (index < 0) return { $push: { watchers: { userId, level } } }; - return { - $set: { - [`watchers.${index}.level`]: level, - }, - }; + if (index < 0) { + return await collection.updateAsync(this._id, { $push: { watchers: { userId, level } } }); + } + return await collection.updateAsync(this._id, { + $set: { [`watchers.${index}.level`]: level }, + }); }, }); }; diff --git a/models/wekanCreator.js b/models/wekanCreator.js index 503cba3fc..39f0fee86 100644 --- a/models/wekanCreator.js +++ b/models/wekanCreator.js @@ -970,7 +970,7 @@ export class WekanCreator { // } } - create(board, currentBoardId) { + async create(board, currentBoardId) { // TODO : Make isSandstorm variable global const isSandstorm = Meteor.settings && @@ -978,7 +978,7 @@ export class WekanCreator { Meteor.settings.public.sandstorm; if (isSandstorm && currentBoardId) { const currentBoard = ReactiveCache.getBoard(currentBoardId); - currentBoard.archive(); + await currentBoard.archive(); } this.parseActivities(board); const boardId = this.createBoardAndLabels(board); diff --git a/packages/wekan-oidc/oidc_server.js b/packages/wekan-oidc/oidc_server.js index 04a304290..a8cb0f2dd 100644 --- a/packages/wekan-oidc/oidc_server.js +++ b/packages/wekan-oidc/oidc_server.js @@ -319,7 +319,7 @@ Meteor.methods({ }); Meteor.methods({ - 'boardRoutineOnLogin': function(info, oidcUserId) + 'boardRoutineOnLogin': async function(info, oidcUserId) { check(info, Object); check(oidcUserId, String); @@ -333,8 +333,8 @@ Meteor.methods({ const memberIndex = _.pluck(board?.members, 'userId').indexOf(userId); if(!board || !userId || memberIndex > -1) return - board.addMember(userId) - board.setMemberPermission( + await board.addMember(userId) + await board.setMemberPermission( userId, defaultBoardParams.contains("isAdmin"), defaultBoardParams.contains("isNoComments"), diff --git a/server/notifications/watch.js b/server/notifications/watch.js index b6e1a6092..3b4907220 100644 --- a/server/notifications/watch.js +++ b/server/notifications/watch.js @@ -1,7 +1,7 @@ import { ReactiveCache } from '/imports/reactiveCache'; Meteor.methods({ - watch(watchableType, id, level) { + async watch(watchableType, id, level) { check(watchableType, String); check(id, String); check(level, Match.OneOf(String, null)); @@ -29,7 +29,7 @@ Meteor.methods({ if (board.permission === 'private' && !board.hasMember(userId)) throw new Meteor.Error('error-board-notAMember'); - watchableObj.setWatcher(userId, level); + await watchableObj.setWatcher(userId, level); return true; }, }); diff --git a/server/publications/swimlanes.js b/server/publications/swimlanes.js index ecf45021c..fec6958c0 100644 --- a/server/publications/swimlanes.js +++ b/server/publications/swimlanes.js @@ -17,7 +17,7 @@ Meteor.methods({ return ret; }, - moveSwimlane(swimlaneId, toBoardId) { + async moveSwimlane(swimlaneId, toBoardId) { check(swimlaneId, String); check(toBoardId, String); @@ -26,7 +26,7 @@ Meteor.methods({ let ret = false; if (swimlane && toBoard) { - swimlane.move(toBoardId); + await swimlane.move(toBoardId); ret = true; } diff --git a/server/rulesHelper.js b/server/rulesHelper.js index d5efe1d3f..b783b407d 100644 --- a/server/rulesHelper.js +++ b/server/rulesHelper.js @@ -1,12 +1,12 @@ import { ReactiveCache } from '/imports/reactiveCache'; RulesHelper = { - executeRules(activity) { + async 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); + await this.performAction(activity, action); } } }, @@ -57,7 +57,7 @@ RulesHelper = { }); return matchingMap; }, - performAction(activity, action) { + async performAction(activity, action) { const card = ReactiveCache.getCard(activity.cardId); const boardId = activity.boardId; if ( @@ -112,12 +112,12 @@ RulesHelper = { const minOrder = _.min( list.cardsUnfiltered(swimlaneId).map(c => c.sort), ); - card.move(action.boardId, swimlaneId, listId, minOrder - 1); + await 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); + await card.move(action.boardId, swimlaneId, listId, maxOrder + 1); } } if (action.actionType === 'sendEmail') { @@ -247,13 +247,13 @@ RulesHelper = { } } if (action.actionType === 'archive') { - card.archive(); + await card.archive(); } if (action.actionType === 'unarchive') { - card.restore(); + await card.restore(); } if (action.actionType === 'setColor') { - card.setColor(action.selectedColor); + await card.setColor(action.selectedColor); } if (action.actionType === 'addLabel') { card.addLabel(action.labelId); @@ -281,14 +281,14 @@ RulesHelper = { title: action.checklistName, cardId: card._id, }); - checkList.checkAllItems(); + await checkList.checkAllItems(); } if (action.actionType === 'uncheckAll') { const checkList = ReactiveCache.getChecklist({ title: action.checklistName, cardId: card._id, }); - checkList.uncheckAllItems(); + await checkList.uncheckAllItems(); } if (action.actionType === 'checkItem') { const checkList = ReactiveCache.getChecklist({ @@ -299,7 +299,7 @@ RulesHelper = { title: action.checkItemName, checkListId: checkList._id, }); - checkItem.check(); + await checkItem.check(); } if (action.actionType === 'uncheckItem') { const checkList = ReactiveCache.getChecklist({ @@ -310,7 +310,7 @@ RulesHelper = { title: action.checkItemName, checkListId: checkList._id, }); - checkItem.uncheck(); + await checkItem.uncheck(); } if (action.actionType === 'addChecklist') { Checklists.insert({