Przeglądaj źródła

Allow swimlanes reordering

Andrés Manelli 7 lat temu
rodzic
commit
37c94622e4

+ 1 - 1
client/components/boards/boardBody.jade

@@ -14,7 +14,7 @@ template(name="board")
 template(name="boardBody")
   .board-wrapper(class=currentBoard.colorClass)
     +sidebar
-    .board-canvas(
+    .board-canvas.js-swimlanes(
       class="{{#if Sidebar.isOpen}}is-sibling-sidebar-open{{/if}}"
       class="{{#if MultiSelection.isActive}}is-multiselection-active{{/if}}"
       class="{{#if draggingActive.get}}is-dragging-active{{/if}}")

+ 0 - 9
client/components/boards/boardBody.styl

@@ -23,15 +23,6 @@ position()
     &.is-sibling-sidebar-open
       margin-right: 248px
 
-    .swimlane
-      border-bottom: 1px solid #CCC
-      display: flex
-      flex-direction: row
-      margin: 0 0 10px
-      padding: 0 40px 5px 0
-      overflow-x: auto
-      overflow-y: hidden
-
     .board-overlay
       position: fixed-cover
       top: -100px

+ 2 - 2
client/components/swimlanes/swimlaneHeader.jade

@@ -1,5 +1,5 @@
 template(name="swimlaneHeader")
-  .swimlane-header-wrap
+  .swimlane-header-wrap.js-swimlane-header
     +inlinedForm
       +editSwimlaneTitleForm
     else
@@ -9,7 +9,7 @@ template(name="swimlaneHeader")
       .swimlane-header-menu
         unless currentUser.isCommentOnly
           a.fa.fa-navicon.js-open-swimlane-menu
-  
+
 template(name="editSwimlaneTitleForm")
   .list-composer
     input.list-name-input.full-line(type="text" value=title autofocus)

+ 1 - 1
client/components/swimlanes/swimlanes.jade

@@ -1,5 +1,5 @@
 template(name="swimlane")
-  .swimlane.js-lists
+  .swimlane.js-lists.js-swimlane
     +swimlaneHeader
     if isMiniScreen
       if currentList

+ 39 - 0
client/components/swimlanes/swimlanes.js

@@ -1,4 +1,43 @@
+const { calculateIndex } = Utils;
+
 BlazeComponent.extendComponent({
+  onRendered() {
+    const boardComponent = this.parentComponent();
+    const $swimlanesDom = boardComponent.$('.js-swimlanes');
+
+    $swimlanesDom.sortable({
+      tolerance: 'pointer',
+      appendTo: 'body',
+      helper: 'clone',
+      handle: '.js-swimlane-header',
+      items: '.js-swimlane:not(.placeholder)',
+      placeholder: 'swimlane placeholder',
+      distance: 7,
+      start(evt, ui) {
+        ui.placeholder.height(ui.helper.height());
+        EscapeActions.executeUpTo('popup-close');
+        boardComponent.setIsDragging(true);
+      },
+      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 prevSwimlaneDom = ui.item.prev('.js-swimlane').get(0);
+        const nextSwimlaneDom = ui.item.next('.js-swimlane').get(0);
+        const sortIndex = calculateIndex(prevSwimlaneDom, nextSwimlaneDom, 1);
+
+        $swimlanesDom.sortable('cancel');
+        const swimlaneDomElement = ui.item.get(0);
+        const swimlane = Blaze.getData(swimlaneDomElement);
+
+        console.log(swimlane._id);
+        Swimlanes.update(swimlane._id, {
+          $set: {
+            sort: sortIndex.base,
+          },
+        });
+      },
+    });
+  },
   onCreated() {
     this.draggingActive = new ReactiveVar(false);
 

+ 48 - 21
client/components/swimlanes/swimlanes.styl

@@ -1,25 +1,52 @@
 @import 'nib'
 
-.swimlane-header-wrap
-  display: flex;
-  flex-direction: row;
-  flex: 0 0 50px;
-  padding-bottom: 30px;
+.swimlane
+  // Even if this background color is the same as the body we can't leave it
+  // transparent, because that won't work during a swimlane drag.
+  background: darken(white, 13%)
+  border-bottom: 1px solid #CCC
+  display: flex
+  flex-direction: row
+  margin: 0 0 10px
+  padding: 0 40px 5px 0
+  overflow-x: auto
+  overflow-y: hidden
 
-  .swimlane-header
-    writing-mode: sideways-lr;
-    font-size: 14px;
-    line-height: 50px;
-    margin-top: 50px;
-    font-weight: bold;
-    min-height: 9px;
-    min-width: 30px;
-    overflow: hidden;
-    -o-text-overflow: ellipsis;
-    text-overflow: ellipsis;
-    word-wrap: break-word;
-    text-align: center;
+  &.placeholder
+    background-color: rgba(0, 0, 0, .2)
+    border-color: transparent
+    box-shadow: none
+    height: 100px
 
-  .swimlane-header-menu
-    position: absolute
-    padding: 20px 20px
+  &.ui-sortable-helper
+    box-shadow: -2px 2px 8px rgba(0, 0, 0, .3),
+                0 0 1px rgba(0, 0, 0, .5)
+    transform: rotate(2deg)
+    cursor: grabbing
+
+    .swimlane-header.ui-sortable-handle
+      cursor: grabbing
+
+  .swimlane-header-wrap
+    display: flex;
+    flex-direction: row;
+    flex: 0 0 50px;
+    padding-bottom: 30px;
+
+    .swimlane-header
+      writing-mode: sideways-lr;
+      font-size: 14px;
+      line-height: 50px;
+      margin-top: 50px;
+      font-weight: bold;
+      min-height: 9px;
+      min-width: 30px;
+      overflow: hidden;
+      -o-text-overflow: ellipsis;
+      text-overflow: ellipsis;
+      word-wrap: break-word;
+      text-align: center;
+
+    .swimlane-header-menu
+      position: absolute
+      padding: 20px 20px