subtasks.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. BlazeComponent.extendComponent({
  2. canModifyCard() {
  3. return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
  4. },
  5. }).register('subtasksDetail');
  6. BlazeComponent.extendComponent({
  7. addSubtask(event) {
  8. event.preventDefault();
  9. const textarea = this.find('textarea.js-add-subtask-item');
  10. const title = textarea.value.trim();
  11. const cardId = this.currentData().cardId;
  12. const card = Cards.findOne(cardId);
  13. if (title) {
  14. Subtasks.insert({
  15. cardId,
  16. title,
  17. sort: card.subtasks().count(),
  18. });
  19. setTimeout(() => {
  20. this.$('.add-subtask-item').last().click();
  21. }, 100);
  22. }
  23. textarea.value = '';
  24. textarea.focus();
  25. },
  26. canModifyCard() {
  27. return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
  28. },
  29. deleteSubtask() {
  30. const subtasks = this.currentData().subtasks;
  31. if (subtasks && subtasks._id) {
  32. Subtasks.remove(subtasks._id);
  33. this.toggleDeleteDialog.set(false);
  34. }
  35. },
  36. editSubtask(event) {
  37. event.preventDefault();
  38. const textarea = this.find('textarea.js-edit-subtasks-item');
  39. const title = textarea.value.trim();
  40. const subtasks = this.currentData().subtasks;
  41. subtasks.setTitle(title);
  42. },
  43. onCreated() {
  44. this.toggleDeleteDialog = new ReactiveVar(false);
  45. this.subtasksToDelete = null; //Store data context to pass to subtaskDeleteDialog template
  46. },
  47. pressKey(event) {
  48. //If user press enter key inside a form, submit it
  49. //Unless the user is also holding down the 'shift' key
  50. if (event.keyCode === 13 && !event.shiftKey) {
  51. event.preventDefault();
  52. const $form = $(event.currentTarget).closest('form');
  53. $form.find('button[type=submit]').click();
  54. }
  55. },
  56. events() {
  57. const events = {
  58. 'click .toggle-delete-subtasks-dialog'(event) {
  59. if($(event.target).hasClass('js-delete-subtasks')){
  60. this.subtasksToDelete = this.currentData().subtasks; //Store data context
  61. }
  62. this.toggleDeleteDialog.set(!this.toggleDeleteDialog.get());
  63. },
  64. };
  65. return [{
  66. ...events,
  67. 'submit .js-add-subtask': this.addSubtask,
  68. 'submit .js-edit-subtasks-title': this.editSubtask,
  69. 'click .confirm-subtasks-delete': this.deleteSubtask,
  70. keydown: this.pressKey,
  71. }];
  72. },
  73. }).register('subtasks');
  74. Template.subtaskDeleteDialog.onCreated(() => {
  75. const $cardDetails = this.$('.card-details');
  76. this.scrollState = { position: $cardDetails.scrollTop(), //save current scroll position
  77. top: false, //required for smooth scroll animation
  78. };
  79. //Callback's purpose is to only prevent scrolling after animation is complete
  80. $cardDetails.animate({ scrollTop: 0 }, 500, () => { this.scrollState.top = true; });
  81. //Prevent scrolling while dialog is open
  82. $cardDetails.on('scroll', () => {
  83. if(this.scrollState.top) { //If it's already in position, keep it there. Otherwise let animation scroll
  84. $cardDetails.scrollTop(0);
  85. }
  86. });
  87. });
  88. Template.subtaskDeleteDialog.onDestroyed(() => {
  89. const $cardDetails = this.$('.card-details');
  90. $cardDetails.off('scroll'); //Reactivate scrolling
  91. $cardDetails.animate( { scrollTop: this.scrollState.position });
  92. });
  93. Template.subtaskItemDetail.helpers({
  94. canModifyCard() {
  95. return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
  96. },
  97. });
  98. BlazeComponent.extendComponent({
  99. // ...
  100. }).register('subtaskItemDetail');