subtasks.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. BlazeComponent.extendComponent({
  2. canModifyCard() {
  3. return (
  4. Meteor.user() &&
  5. Meteor.user().isBoardMember() &&
  6. !Meteor.user().isCommentOnly() &&
  7. !Meteor.user().isWorker()
  8. );
  9. },
  10. }).register('subtaskDetail');
  11. BlazeComponent.extendComponent({
  12. addSubtask(event) {
  13. event.preventDefault();
  14. const textarea = this.find('textarea.js-add-subtask-item');
  15. const title = textarea.value.trim();
  16. const cardId = this.currentData().cardId;
  17. const card = Cards.findOne(cardId);
  18. const sortIndex = -1;
  19. const crtBoard = Boards.findOne(card.boardId);
  20. const targetBoard = crtBoard.getDefaultSubtasksBoard();
  21. const listId = targetBoard.getDefaultSubtasksListId();
  22. //Get the full swimlane data for the parent task.
  23. const parentSwimlane = Swimlanes.findOne({
  24. boardId: crtBoard._id,
  25. _id: card.swimlaneId,
  26. });
  27. //find the swimlane of the same name in the target board.
  28. const targetSwimlane = Swimlanes.findOne({
  29. boardId: targetBoard._id,
  30. title: parentSwimlane.title,
  31. });
  32. //If no swimlane with a matching title exists in the target board, fall back to the default swimlane.
  33. const swimlaneId =
  34. targetSwimlane === undefined
  35. ? targetBoard.getDefaultSwimline()._id
  36. : targetSwimlane._id;
  37. const nextCardNumber = targetBoard.getNextCardNumber();
  38. if (title) {
  39. const _id = Cards.insert({
  40. title,
  41. parentId: cardId,
  42. members: [],
  43. labelIds: [],
  44. customFields: [],
  45. listId,
  46. boardId: targetBoard._id,
  47. sort: sortIndex,
  48. swimlaneId,
  49. type: 'cardType-card',
  50. cardNumber: nextCardNumber
  51. });
  52. // In case the filter is active we need to add the newly inserted card in
  53. // the list of exceptions -- cards that are not filtered. Otherwise the
  54. // card will disappear instantly.
  55. // See https://github.com/wekan/wekan/issues/80
  56. Filter.addException(_id);
  57. setTimeout(() => {
  58. this.$('.add-subtask-item')
  59. .last()
  60. .click();
  61. }, 100);
  62. }
  63. textarea.value = '';
  64. textarea.focus();
  65. },
  66. canModifyCard() {
  67. return (
  68. Meteor.user() &&
  69. Meteor.user().isBoardMember() &&
  70. !Meteor.user().isCommentOnly() &&
  71. !Meteor.user().isWorker()
  72. );
  73. },
  74. deleteSubtask() {
  75. const subtask = this.currentData().subtask;
  76. if (subtask && subtask._id) {
  77. subtask.archive();
  78. }
  79. },
  80. editSubtask(event) {
  81. event.preventDefault();
  82. const textarea = this.find('textarea.js-edit-subtask-item');
  83. const title = textarea.value.trim();
  84. const subtask = this.currentData().subtask;
  85. subtask.setTitle(title);
  86. },
  87. pressKey(event) {
  88. //If user press enter key inside a form, submit it
  89. //Unless the user is also holding down the 'shift' key
  90. if (event.keyCode === 13 && !event.shiftKey) {
  91. event.preventDefault();
  92. const $form = $(event.currentTarget).closest('form');
  93. $form.find('button[type=submit]').click();
  94. }
  95. },
  96. events() {
  97. return [
  98. {
  99. 'click .js-open-subtask-details-menu': Popup.open('subtaskActions'),
  100. 'submit .js-add-subtask': this.addSubtask,
  101. 'submit .js-edit-subtask-title': this.editSubtask,
  102. 'click .js-delete-subtask-item': this.deleteSubtask,
  103. keydown: this.pressKey,
  104. },
  105. ];
  106. },
  107. }).register('subtasks');
  108. Template.subtaskItemDetail.helpers({
  109. canModifyCard() {
  110. return (
  111. Meteor.user() &&
  112. Meteor.user().isBoardMember() &&
  113. !Meteor.user().isCommentOnly() &&
  114. !Meteor.user().isWorker()
  115. );
  116. },
  117. });
  118. BlazeComponent.extendComponent({
  119. // ...
  120. }).register('subtaskItemDetail');
  121. BlazeComponent.extendComponent({
  122. events() {
  123. return [
  124. {
  125. 'click .js-view-subtask'(event) {
  126. if ($(event.target).hasClass('js-view-subtask')) {
  127. const subtask = this.currentData().subtask;
  128. const board = subtask.board();
  129. FlowRouter.go('card', {
  130. boardId: board._id,
  131. slug: board.slug,
  132. cardId: subtask._id,
  133. });
  134. }
  135. },
  136. 'click .js-delete-subtask' : Popup.afterConfirm('subtaskDelete', function () {
  137. Popup.back(2);
  138. const subtask = this.subtask;
  139. if (subtask && subtask._id) {
  140. subtask.archive();
  141. }
  142. }),
  143. }
  144. ]
  145. }
  146. }).register('subtaskActionsPopup');