Browse Source

Merge branch 'jrsupplee-move-swimlane'

Lauri Ojansivu 4 years ago
parent
commit
10c9fc25a9

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

@@ -39,6 +39,8 @@ template(name="swimlaneActionPopup")
       hr
       ul.pop-over-list
         li: a.js-close-swimlane {{_ 'archive-swimlane'}}
+      ul.pop-over-list
+        li: a.js-move-swimlane {{_ 'move-swimlane'}}
 
 template(name="swimlaneAddPopup")
   unless currentUser.isCommentOnly

+ 16 - 11
client/components/swimlanes/swimlaneHeader.js

@@ -47,20 +47,25 @@ Template.swimlaneFixedHeader.helpers({
   },
 });
 
-Template.swimlaneActionPopup.events({
-  'click .js-set-swimlane-color': Popup.open('setSwimlaneColor'),
-  'click .js-close-swimlane'(event) {
-    event.preventDefault();
-    this.archive();
-    Popup.close();
-  },
-});
-
-Template.swimlaneActionPopup.helpers({
+BlazeComponent.extendComponent({
   isCommentOnly() {
     return Meteor.user().isCommentOnly();
   },
-});
+
+  events() {
+    return [
+      {
+        'click .js-set-swimlane-color': Popup.open('setSwimlaneColor'),
+        'click .js-close-swimlane'(event) {
+          event.preventDefault();
+          this.archive();
+          Popup.close();
+        },
+        'click .js-move-swimlane': Popup.open('moveSwimlane'),
+      },
+    ];
+  },
+}).register('swimlaneActionPopup');
 
 BlazeComponent.extendComponent({
   onCreated() {

+ 10 - 0
client/components/swimlanes/swimlanes.jade

@@ -61,3 +61,13 @@ template(name="addListForm")
             a.open-list-composer.js-open-inlined-form
               i.fa.fa-plus
               | {{_ 'add-list'}}
+
+template(name="moveSwimlanePopup")
+  unless currentUser.isWorker
+    label {{_ 'boards'}}:
+    select.js-select-boards(autofocus)
+      each toBoard in toBoards
+        option(value="{{toBoard._id}}") {{toBoard.title}}
+
+  .edit-controls.clearfix
+    button.primary.confirm.js-done {{_ 'done'}}

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

@@ -323,3 +323,46 @@ BlazeComponent.extendComponent({
     initSortable(boardComponent, $listsDom);
   },
 }).register('listsGroup');
+
+BlazeComponent.extendComponent({
+  onCreated() {
+    this.currentSwimlane = this.currentData();
+  },
+
+  board() {
+    return Boards.findOne(Session.get('currentBoard'));
+  },
+
+  toBoards() {
+    const boards = Boards.find(
+      {
+        archived: false,
+        'members.userId': Meteor.userId(),
+        type: 'board',
+        _id: { $ne: this.board()._id },
+      },
+      {
+        sort: { title: 1 },
+      },
+    );
+
+    return boards;
+  },
+
+  events() {
+    return [
+      {
+        'click .js-done'() {
+          const swimlane = Swimlanes.findOne(this.currentSwimlane._id);
+          const bSelect = $('.js-select-boards')[0];
+          let boardId;
+          if (bSelect) {
+            boardId = bSelect.options[bSelect.selectedIndex].value;
+            Meteor.call('moveSwimlane', this.currentSwimlane._id, boardId);
+          }
+          Popup.close();
+        },
+      },
+    ];
+  },
+}).register('moveSwimlanePopup');

+ 3 - 1
i18n/en.i18n.json

@@ -984,5 +984,7 @@
   "created-at-oldest-first": "Created At (Oldest First)",
   "links-heading": "Links",
   "hide-system-messages-of-all-users": "Hide system messages of all users",
-  "now-system-messages-of-all-users-are-hidden": "Now system messages of all users are hidden"
+  "now-system-messages-of-all-users-are-hidden": "Now system messages of all users are hidden",
+  "move-swimlane": "Move Swimlane",
+  "moveSwimlanePopup-title": "Move Swimlane"
 }

+ 5 - 2
models/cards.js

@@ -1527,14 +1527,17 @@ Cards.mutations({
     return this.move(boardId, swimlaneId, listId, sort);
   },
 
-  move(boardId, swimlaneId, listId, sort) {
+  move(boardId, swimlaneId, listId, sort=null) {
     const mutatedFields = {
       boardId,
       swimlaneId,
       listId,
-      sort,
     };
 
+    if (sort !== null) {
+      mutatedFields.sort = sort;
+    }
+
     // we must only copy the labels and custom fields if the target board
     // differs from the source board
     if (this.boardId !== boardId) {

+ 30 - 1
models/lists.js

@@ -202,7 +202,7 @@ Lists.helpers({
     this.swimlaneId = swimlaneId;
 
     let _id = null;
-    existingListWithSameName = Lists.findOne({
+    const existingListWithSameName = Lists.findOne({
       boardId,
       title: this.title,
       archived: false,
@@ -225,6 +225,35 @@ Lists.helpers({
     });
   },
 
+  move(boardId, swimlaneId) {
+    const boardList = Lists.findOne({
+      boardId,
+      title: this.title,
+      archived: false,
+    });
+    let listId;
+    if (boardList) {
+      listId = boardList._id;
+      this.cards().forEach(card => {
+        card.move(boardId, this._id, boardList._id);
+      });
+    } else {
+      console.log('list.title:', this.title);
+      console.log('boardList:', boardList);
+      listId = Lists.insert({
+        title: this.title,
+        boardId,
+        type: this.type,
+        archived: false,
+        wipLimit: this.wipLimit,
+      });
+    }
+
+    this.cards(swimlaneId).forEach(card => {
+      card.move(boardId, swimlaneId, listId);
+    });
+  },
+
   cards(swimlaneId) {
     const selector = {
       listId: this._id,

+ 53 - 0
server/publications/swimlanes.js

@@ -0,0 +1,53 @@
+Meteor.methods({
+  moveSwimlane(swimlaneId, toBoardId) {
+    check(swimlaneId, String);
+    check(toBoardId, String);
+
+    const swimlane = Swimlanes.findOne(swimlaneId);
+    const fromBoard = Boards.findOne(swimlane.boardId);
+    const toBoard = Boards.findOne(toBoardId);
+
+    if (swimlane && toBoard) {
+      swimlane.lists().forEach(list => {
+        const toList = Lists.findOne({
+          boardId: toBoardId,
+          title: list.title,
+          archived: false,
+        });
+
+        let toListId;
+        if (toList) {
+          toListId = toList._id;
+        } else {
+          toListId = Lists.insert({
+            title: list.title,
+            boardId: toBoardId,
+            type: list.type,
+            archived: false,
+            wipLimit: list.wipLimit,
+          });
+        }
+
+        Cards.find({
+          listId: list._id,
+          swimlaneId,
+        }).forEach(card => {
+          card.move(toBoardId, swimlaneId, toListId);
+        });
+      });
+
+      Swimlanes.update(swimlaneId, {
+        $set: {
+          boardId: toBoardId,
+        },
+      });
+
+      // make sure there is a default swimlane
+      fromBoard.getDefaultSwimline();
+
+      return true;
+    }
+
+    return false;
+  },
+});