boardBody.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. BlazeComponent.extendComponent({
  2. template: function() {
  3. return 'boardComponent';
  4. },
  5. onCreated: function() {
  6. this.draggingActive = new ReactiveVar(false);
  7. this.showOverlay = new ReactiveVar(false);
  8. },
  9. openNewListForm: function() {
  10. this.componentChildren('addListForm')[0].open();
  11. },
  12. // XXX Flow components allow us to avoid creating these two setter methods by
  13. // exposing a public API to modify the component state. We need to investigate
  14. // best practices here.
  15. setIsDragging: function(bool) {
  16. this.draggingActive.set(bool);
  17. },
  18. scrollLeft: function(position) {
  19. position = position || 0;
  20. var $container = $(this.find('.js-lists'));
  21. var containerWidth = $container.width();
  22. var currentScrollPosition = $container.scrollLeft();
  23. if (position < currentScrollPosition) {
  24. $container.animate({
  25. scrollLeft: position
  26. });
  27. } else if (position > currentScrollPosition + containerWidth) {
  28. $container.animate({
  29. scrollLeft: Math.max(0, position - containerWidth)
  30. });
  31. }
  32. },
  33. currentCardIsInThisList: function() {
  34. var currentCard = Cards.findOne(Session.get('currentCard'));
  35. var listId = this.currentData()._id;
  36. return currentCard && currentCard.listId === listId;
  37. },
  38. onRendered: function() {
  39. var self = this;
  40. self.scrollLeft();
  41. var lists = this.find('.js-lists');
  42. // We want to animate the card details window closing. We rely on CSS
  43. // transition for the actual animation.
  44. lists._uihooks = {
  45. removeElement: function(node) {
  46. var removeNode = _.once(function() {
  47. node.parentNode.removeChild(node);
  48. });
  49. if ($(node).hasClass('js-card-details')) {
  50. $(node).css({
  51. flexBasis: 0,
  52. padding: 0
  53. });
  54. $(lists).one(CSSEvents.transitionend, removeNode);
  55. } else {
  56. removeNode();
  57. }
  58. }
  59. };
  60. if (! Meteor.userId() || ! Meteor.user().isBoardMember())
  61. return;
  62. self.$(lists).sortable({
  63. tolerance: 'pointer',
  64. helper: 'clone',
  65. items: '.js-list:not(.js-list-composer)',
  66. placeholder: 'list placeholder',
  67. distance: 7,
  68. start: function(evt, ui) {
  69. ui.placeholder.height(ui.helper.height());
  70. Popup.close();
  71. },
  72. stop: function() {
  73. self.$('.js-lists').find('.js-list:not(.js-list-composer)').each(
  74. function(i, list) {
  75. var data = Blaze.getData(list);
  76. Lists.update(data._id, {
  77. $set: {
  78. sort: i
  79. }
  80. });
  81. }
  82. );
  83. }
  84. });
  85. // Disable drag-dropping while in multi-selection mode
  86. self.autorun(function() {
  87. self.$(lists).sortable('option', 'disabled', MultiSelection.isActive());
  88. });
  89. // If there is no data in the board (ie, no lists) we autofocus the list
  90. // creation form by clicking on the corresponding element.
  91. if (self.data().lists().count() === 0) {
  92. this.openNewListForm();
  93. }
  94. },
  95. sidebarSize: function() {
  96. var sidebar = this.componentChildren('sidebar')[0];
  97. if (sidebar && sidebar.isOpen())
  98. return 'next-sidebar';
  99. },
  100. events: function() {
  101. return [{
  102. // XXX The board-overlay div should probably be moved to the parent
  103. // component.
  104. 'mouseenter .board-overlay': function() {
  105. this.showOverlay.set(false);
  106. }
  107. }];
  108. }
  109. }).register('boardComponent');
  110. BlazeComponent.extendComponent({
  111. template: function() {
  112. return 'addListForm';
  113. },
  114. // Proxy
  115. open: function() {
  116. this.componentChildren('inlinedForm')[0].open();
  117. },
  118. events: function() {
  119. return [{
  120. submit: function(evt) {
  121. evt.preventDefault();
  122. var title = this.find('.list-name-input');
  123. if ($.trim(title.value)) {
  124. Lists.insert({
  125. title: title.value,
  126. boardId: Session.get('currentBoard'),
  127. sort: $('.list').length
  128. });
  129. title.value = '';
  130. }
  131. }
  132. }];
  133. }
  134. }).register('addListForm');