Przeglądaj źródła

Add copy swimlane functionality

John R. Supplee 4 lat temu
rodzic
commit
4940af0573

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

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

+ 1 - 0
client/components/swimlanes/swimlaneHeader.js

@@ -55,6 +55,7 @@ Template.swimlaneActionPopup.events({
     Popup.close();
     Popup.close();
   },
   },
   'click .js-move-swimlane': Popup.open('moveSwimlane'),
   'click .js-move-swimlane': Popup.open('moveSwimlane'),
+  'click .js-copy-swimlane': Popup.open('copySwimlane'),
 });
 });
 
 
 Template.swimlaneActionPopup.events({
 Template.swimlaneActionPopup.events({

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

@@ -71,3 +71,13 @@ template(name="moveSwimlanePopup")
 
 
   .edit-controls.clearfix
   .edit-controls.clearfix
     button.primary.confirm.js-done {{_ 'done'}}
     button.primary.confirm.js-done {{_ 'done'}}
+
+template(name="copySwimlanePopup")
+  unless currentUser.isWorker
+    label {{_ 'boards'}}:
+    select.js-select-boards(autofocus)
+      each toBoard in toBoards
+        option(value="{{toBoard._id}}" selected="{{#if $eq toBoard.title board.title}}1{{/if}}") {{toBoard.title}}
+
+  .edit-controls.clearfix
+    button.primary.confirm.js-done {{_ 'done'}}

+ 30 - 21
client/components/swimlanes/swimlanes.js

@@ -324,45 +324,54 @@ BlazeComponent.extendComponent({
   },
   },
 }).register('listsGroup');
 }).register('listsGroup');
 
 
-BlazeComponent.extendComponent({
+class MoveSwimlaneComponent extends BlazeComponent {
+  serverMethod = 'moveSwimlane';
+
   onCreated() {
   onCreated() {
     this.currentSwimlane = this.currentData();
     this.currentSwimlane = this.currentData();
-  },
+  }
 
 
   board() {
   board() {
     return Boards.findOne(Session.get('currentBoard'));
     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 },
-      },
-    );
+  toBoardsSelector() {
+    return {
+      archived: false,
+      'members.userId': Meteor.userId(),
+      type: 'board',
+      _id: { $ne: this.board()._id },
+    };
+  }
 
 
-    return boards;
-  },
+  toBoards() {
+    return Boards.find(this.toBoardsSelector(), { sort: { title: 1 } });
+  }
 
 
   events() {
   events() {
     return [
     return [
       {
       {
         'click .js-done'() {
         'click .js-done'() {
-          const swimlane = Swimlanes.findOne(this.currentSwimlane._id);
+          // const swimlane = Swimlanes.findOne(this.currentSwimlane._id);
           const bSelect = $('.js-select-boards')[0];
           const bSelect = $('.js-select-boards')[0];
           let boardId;
           let boardId;
           if (bSelect) {
           if (bSelect) {
             boardId = bSelect.options[bSelect.selectedIndex].value;
             boardId = bSelect.options[bSelect.selectedIndex].value;
-            Meteor.call('moveSwimlane', this.currentSwimlane._id, boardId);
+            Meteor.call(this.serverMethod, this.currentSwimlane._id, boardId);
           }
           }
           Popup.close();
           Popup.close();
         },
         },
       },
       },
     ];
     ];
-  },
-}).register('moveSwimlanePopup');
+  }
+}
+MoveSwimlaneComponent.register('moveSwimlanePopup');
+
+(class extends MoveSwimlaneComponent {
+  serverMethod = 'copySwimlane';
+  toBoardsSelector() {
+    const selector = super.toBoardsSelector();
+    delete selector._id;
+    return selector;
+  }
+}.register('copySwimlanePopup'));

+ 3 - 1
i18n/en.i18n.json

@@ -1005,5 +1005,7 @@
   "filesReportTitle": "Files Report",
   "filesReportTitle": "Files Report",
   "orphanedFilesReportTitle": "Orphaned Files Report",
   "orphanedFilesReportTitle": "Orphaned Files Report",
   "reports": "Reports",
   "reports": "Reports",
-  "rulesReportTitle": "Rules Report"
+  "rulesReportTitle": "Rules Report",
+  "copy-swimlane": "Copy Swimlane",
+  "copySwimlanePopup-title": "Copy Swimlane"
 }
 }

+ 39 - 0
models/swimlanes.js

@@ -147,6 +147,45 @@ Swimlanes.helpers({
     });
     });
   },
   },
 
 
+  move(toBoardId) {
+    this.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: this._id,
+      }).forEach(card => {
+        card.move(toBoardId, this._id, toListId);
+      });
+    });
+
+    Swimlanes.update(this._id, {
+      $set: {
+        boardId: toBoardId,
+      },
+    });
+
+    // make sure there is a default swimlane
+    this.board().getDefaultSwimline();
+  },
+
   cards() {
   cards() {
     return Cards.find(
     return Cards.find(
       Filter.mongoSelector({
       Filter.mongoSelector({

+ 16 - 37
server/publications/swimlanes.js

@@ -1,49 +1,28 @@
 Meteor.methods({
 Meteor.methods({
+  copySwimlane(swimlaneId, toBoardId) {
+    check(swimlaneId, String);
+    check(toBoardId, String);
+
+    const swimlane = Swimlanes.findOne(swimlaneId);
+    const toBoard = Boards.findOne(toBoardId);
+
+    if (swimlane && toBoard) {
+      swimlane.copy(toBoardId);
+      return true;
+    }
+
+    return false;
+  },
+
   moveSwimlane(swimlaneId, toBoardId) {
   moveSwimlane(swimlaneId, toBoardId) {
     check(swimlaneId, String);
     check(swimlaneId, String);
     check(toBoardId, String);
     check(toBoardId, String);
 
 
     const swimlane = Swimlanes.findOne(swimlaneId);
     const swimlane = Swimlanes.findOne(swimlaneId);
-    const fromBoard = Boards.findOne(swimlane.boardId);
     const toBoard = Boards.findOne(toBoardId);
     const toBoard = Boards.findOne(toBoardId);
 
 
     if (swimlane && toBoard) {
     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();
+      swimlane.move(toBoardId);
 
 
       return true;
       return true;
     }
     }