Pārlūkot izejas kodu

Make boards sortable

boeserwolf 5 gadi atpakaļ
vecāks
revīzija
ef5f38f431

+ 2 - 2
client/components/boards/boardsList.jade

@@ -1,10 +1,10 @@
 template(name="boardList")
 template(name="boardList")
   .wrapper
   .wrapper
-    ul.board-list.clearfix
+    ul.board-list.clearfix.js-boards
       li.js-add-board
       li.js-add-board
         a.board-list-item.label {{_ 'add-board'}}
         a.board-list-item.label {{_ 'add-board'}}
       each boards
       each boards
-        li(class="{{#if isStarred}}starred{{/if}}" class=colorClass)
+        li(class="{{#if isStarred}}starred{{/if}}" class=colorClass).js-board
           if isInvited
           if isInvited
             .board-list-item
             .board-list-item
               span.details
               span.details

+ 54 - 0
client/components/boards/boardsList.js

@@ -1,4 +1,5 @@
 const subManager = new SubsManager();
 const subManager = new SubsManager();
+const { calculateIndex, enableClickOnTouch } = Utils;
 
 
 Template.boardListHeaderBar.events({
 Template.boardListHeaderBar.events({
   'click .js-open-archived-board'() {
   'click .js-open-archived-board'() {
@@ -23,6 +24,59 @@ BlazeComponent.extendComponent({
     Meteor.subscribe('setting');
     Meteor.subscribe('setting');
   },
   },
 
 
+  onRendered() {
+    const self = this;
+    function userIsAllowedToMove() {
+      return Meteor.user();
+    }
+
+    const itemsSelector = '.js-board:not(.placeholder)';
+
+    const $boards = this.$('.js-boards');
+    $boards.sortable({
+      connectWith: '.js-boards',
+      tolerance: 'pointer',
+      appendTo: '.board-list',
+      helper: 'clone',
+      distance: 7,
+      items: itemsSelector,
+      placeholder: 'board-wrapper placeholder',
+      start(evt, ui) {
+        ui.helper.css('z-index', 1000);
+        ui.placeholder.height(ui.helper.height());
+        EscapeActions.executeUpTo('popup-close');
+      },
+      stop(evt, ui) {
+        // To attribute the new index number, we need to get the DOM element
+        // of the previous and the following card -- if any.
+        const prevCardDom = ui.item.prev('.js-board').get(0);
+        const nextCardDom = ui.item.next('.js-board').get(0);
+        const sortIndex = calculateIndex(prevCardDom, nextCardDom, 1);
+
+        const boardDomElement = ui.item.get(0);
+        const board = Blaze.getData(boardDomElement);
+        // Normally the jquery-ui sortable library moves the dragged DOM element
+        // to its new position, which disrupts Blaze reactive updates mechanism
+        // (especially when we move the last card of a list, or when multiple
+        // users move some cards at the same time). To prevent these UX glitches
+        // we ask sortable to gracefully cancel the move, and to put back the
+        // DOM in its initial state. The card move is then handled reactively by
+        // Blaze with the below query.
+        $boards.sortable('cancel');
+
+        board.move(sortIndex.base);
+      },
+    });
+
+    // ugly touch event hotfix
+    enableClickOnTouch(itemsSelector);
+
+    // Disable drag-dropping if the current user is not a board member or is comment only
+    this.autorun(() => {
+      $boards.sortable('option', 'disabled', !userIsAllowedToMove());
+    });
+  },
+
   boards() {
   boards() {
     let query = {
     let query = {
       archived: false,
       archived: false,

+ 14 - 1
client/components/boards/boardsList.styl

@@ -11,6 +11,19 @@ $spaceBetweenTiles = 16px
     box-sizing: border-box
     box-sizing: border-box
     position: relative
     position: relative
 
 
+    &.placeholder:after
+      content: '';
+      display: block;
+      background: darken(white, 20%)
+      border-radius: 3px;
+      height: 106px;
+      margin: 8px;
+
+    &.ui-sortable-helper
+      cursor: grabbing
+      transform: rotate(4deg)
+      display: block !important
+
     &.starred
     &.starred
       .fa-star,
       .fa-star,
       .fa-star-o
       .fa-star-o
@@ -183,7 +196,7 @@ $spaceBetweenTiles = 16px
     overflow: scroll
     overflow: scroll
 
 
     li
     li
-      width: 50% 
+      width: 50%
 
 
     .board-list-item
     .board-list-item
       overflow: hidden
       overflow: hidden