2
0

boardBody.js 4.0 KB

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