Procházet zdrojové kódy

Fixed #2338 -> Slow opening of big boards with too many archived items

wekan před 6 roky
rodič
revize
ab4fec0f3c

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

@@ -14,7 +14,7 @@ BlazeComponent.extendComponent({
       const currentBoardId = Session.get('currentBoard');
       if (!currentBoardId)
         return;
-      const handle = subManager.subscribe('board', currentBoardId);
+      const handle = subManager.subscribe('board', currentBoardId, false);
       Tracker.nonreactive(() => {
         Tracker.autorun(() => {
           this.isBoardReady.set(handle.ready());

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

@@ -33,12 +33,12 @@ BlazeComponent.extendComponent({
   },
 
   hasOvertimeCards() {
-    subManager.subscribe('board', this.currentData()._id);
+    subManager.subscribe('board', this.currentData()._id, false);
     return this.currentData().hasOvertimeCards();
   },
 
   hasSpentTimeCards() {
-    subManager.subscribe('board', this.currentData()._id);
+    subManager.subscribe('board', this.currentData()._id, false);
     return this.currentData().hasSpentTimeCards();
   },
 

+ 3 - 3
client/components/cards/cardDetails.js

@@ -424,7 +424,7 @@ Template.moveCardPopup.events({
 });
 BlazeComponent.extendComponent({
   onCreated() {
-    subManager.subscribe('board', Session.get('currentBoard'));
+    subManager.subscribe('board', Session.get('currentBoard'), false);
     this.selectedBoardId = new ReactiveVar(Session.get('currentBoard'));
   },
 
@@ -453,7 +453,7 @@ BlazeComponent.extendComponent({
     return [{
       'change .js-select-boards'(evt) {
         this.selectedBoardId.set($(evt.currentTarget).val());
-        subManager.subscribe('board', this.selectedBoardId.get());
+        subManager.subscribe('board', this.selectedBoardId.get(), false);
       },
     }];
   },
@@ -676,7 +676,7 @@ BlazeComponent.extendComponent({
         if (selection === 'none') {
           this.parentBoard.set(null);
         } else {
-          subManager.subscribe('board', $(evt.currentTarget).val());
+          subManager.subscribe('board', $(evt.currentTarget).val(), false);
           this.parentBoard.set(selection);
           list.prop('disabled', false);
         }

+ 6 - 6
client/components/lists/listBody.js

@@ -348,7 +348,7 @@ BlazeComponent.extendComponent({
 
     this.boardId = Session.get('currentBoard');
     // In order to get current board info
-    subManager.subscribe('board', this.boardId);
+    subManager.subscribe('board', this.boardId, false);
     this.board = Boards.findOne(this.boardId);
     // List where to insert card
     const list = $(Popup._getTopStack().openerElement).closest('.js-list');
@@ -414,7 +414,7 @@ BlazeComponent.extendComponent({
   events() {
     return [{
       'change .js-select-boards'(evt) {
-        subManager.subscribe('board', $(evt.currentTarget).val());
+        subManager.subscribe('board', $(evt.currentTarget).val(), false);
         this.selectedBoardId.set($(evt.currentTarget).val());
       },
       'change .js-select-swimlanes'(evt) {
@@ -500,13 +500,13 @@ BlazeComponent.extendComponent({
     }
     const boardId = board._id;
     // Subscribe to this board
-    subManager.subscribe('board', boardId);
+    subManager.subscribe('board', boardId, false);
     this.selectedBoardId = new ReactiveVar(boardId);
 
     if (!this.isBoardTemplateSearch) {
       this.boardId = Session.get('currentBoard');
       // In order to get current board info
-      subManager.subscribe('board', this.boardId);
+      subManager.subscribe('board', this.boardId, false);
       this.swimlaneId = '';
       // Swimlane where to insert card
       const swimlane = $(Popup._getTopStack().openerElement).parents('.js-swimlane');
@@ -547,7 +547,7 @@ BlazeComponent.extendComponent({
     } else if (this.isBoardTemplateSearch) {
       const boards = board.searchBoards(this.term.get());
       boards.forEach((board) => {
-        subManager.subscribe('board', board.linkedId);
+        subManager.subscribe('board', board.linkedId, false);
       });
       return boards;
     } else {
@@ -558,7 +558,7 @@ BlazeComponent.extendComponent({
   events() {
     return [{
       'change .js-select-boards'(evt) {
-        subManager.subscribe('board', $(evt.currentTarget).val());
+        subManager.subscribe('board', $(evt.currentTarget).val(), false);
         this.selectedBoardId.set($(evt.currentTarget).val());
       },
       'submit .js-search-term-form'(evt) {

+ 49 - 47
client/components/sidebar/sidebarArchives.jade

@@ -1,54 +1,56 @@
 template(name="archivesSidebar")
-  +basicTabs(tabs=tabs)
-
-   +tabContent(slug="cards")
-    p.quiet
-      a.js-restore-all-cards {{_ 'restore-all'}}
-      | -
-      a.js-delete-all-cards {{_ 'delete-all'}}
-    each archivedCards
-      .minicard-wrapper.js-minicard
-        +minicard(this)
-      if currentUser.isBoardMember
+  if isArchiveReady.get
+    +basicTabs(tabs=tabs)
+      +tabContent(slug="cards")
         p.quiet
-          a.js-restore-card {{_ 'restore'}}
+          a.js-restore-all-cards {{_ 'restore-all'}}
           | -
-          a.js-delete-card {{_ 'delete'}}
-        if cardIsInArchivedList
-          p.quiet.small ({{_ 'warn-list-archived'}})
-    else
-      p.no-items-message {{_ 'no-archived-cards'}}
-
-   +tabContent(slug="lists")
-    p.quiet
-      a.js-restore-all-lists {{_ 'restore-all'}}
-      | -
-      a.js-delete-all-lists {{_ 'delete-all'}}
-    ul.archived-lists
-      each archivedLists
-        li.archived-lists-item
-          = title
+          a.js-delete-all-cards {{_ 'delete-all'}}
+        each archivedCards
+          .minicard-wrapper.js-minicard
+            +minicard(this)
           if currentUser.isBoardMember
             p.quiet
-              a.js-restore-list {{_ 'restore'}}
+              a.js-restore-card {{_ 'restore'}}
               | -
-              a.js-delete-list {{_ 'delete'}}
-      else
-        li.no-items-message {{_ 'no-archived-lists'}}
+              a.js-delete-card {{_ 'delete'}}
+            if cardIsInArchivedList
+              p.quiet.small ({{_ 'warn-list-archived'}})
+        else
+          p.no-items-message {{_ 'no-archived-cards'}}
 
-   +tabContent(slug="swimlanes")
-    p.quiet
-      a.js-restore-all-swimlanes {{_ 'restore-all'}}
-      | -
-      a.js-delete-all-swimlanes {{_ 'delete-all'}}
-    ul.archived-lists
-      each archivedSwimlanes
-        li.archived-lists-item
-          = title
-          if currentUser.isBoardMember
-            p.quiet
-              a.js-restore-swimlane {{_ 'restore'}}
-              | -
-              a.js-delete-swimlane {{_ 'delete'}}
-      else
-        li.no-items-message {{_ 'no-archived-swimlanes'}}
+      +tabContent(slug="lists")
+        p.quiet
+          a.js-restore-all-lists {{_ 'restore-all'}}
+          | -
+          a.js-delete-all-lists {{_ 'delete-all'}}
+        ul.archived-lists
+          each archivedLists
+            li.archived-lists-item
+              = title
+              if currentUser.isBoardMember
+                p.quiet
+                  a.js-restore-list {{_ 'restore'}}
+                  | -
+                  a.js-delete-list {{_ 'delete'}}
+          else
+            li.no-items-message {{_ 'no-archived-lists'}}
+
+      +tabContent(slug="swimlanes")
+        p.quiet
+          a.js-restore-all-swimlanes {{_ 'restore-all'}}
+          | -
+          a.js-delete-all-swimlanes {{_ 'delete-all'}}
+        ul.archived-lists
+          each archivedSwimlanes
+            li.archived-lists-item
+              = title
+              if currentUser.isBoardMember
+                p.quiet
+                  a.js-restore-swimlane {{_ 'restore'}}
+                  | -
+                  a.js-delete-swimlane {{_ 'delete'}}
+          else
+            li.no-items-message {{_ 'no-archived-swimlanes'}}
+  else
+    +spinner

+ 22 - 0
client/components/sidebar/sidebarArchives.js

@@ -1,4 +1,26 @@
+const subManager = new SubsManager();
+
 BlazeComponent.extendComponent({
+  onCreated() {
+    this.isArchiveReady = new ReactiveVar(false);
+
+    // The pattern we use to manually handle data loading is described here:
+    // https://kadira.io/academy/meteor-routing-guide/content/subscriptions-and-data-management/using-subs-manager
+    // XXX The boardId should be readed from some sort the component "props",
+    // unfortunatly, Blaze doesn't have this notion.
+    this.autorun(() => {
+      const currentBoardId = Session.get('currentBoard');
+      if (!currentBoardId)
+        return;
+      const handle = subManager.subscribe('board', currentBoardId, true);
+      Tracker.nonreactive(() => {
+        Tracker.autorun(() => {
+          this.isArchiveReady.set( handle.ready() );
+        });
+      });
+    });
+  },
+
   tabs() {
     return [
       { name: TAPi18n.__('cards'), slug: 'cards' },

+ 8 - 4
server/publications/boards.js

@@ -59,9 +59,12 @@ Meteor.publish('archivedBoards', function() {
   });
 });
 
-Meteor.publishRelations('board', function(boardId) {
+// If isArchived = false, this will only return board elements which are not archived.
+// If isArchived = true, this will only return board elements which are archived.
+Meteor.publishRelations('board', function(boardId, isArchived) {
   this.unblock();
   check(boardId, String);
+  check(isArchived, Boolean);
   const thisUserId = this.userId;
 
   this.cursor(Boards.find({
@@ -75,8 +78,8 @@ Meteor.publishRelations('board', function(boardId) {
     ],
   // Sort required to ensure oplog usage
   }, { limit: 1, sort: { _id: 1 } }), function(boardId, board) {
-    this.cursor(Lists.find({ boardId }));
-    this.cursor(Swimlanes.find({ boardId }));
+    this.cursor(Lists.find({ boardId: boardId, archived: isArchived }));
+    this.cursor(Swimlanes.find({ boardId: boardId,  archived: isArchived  }));
     this.cursor(Integrations.find({ boardId }));
     this.cursor(CustomFields.find({ boardIds: {$in: [boardId]} }, { sort: { name: 1 } }));
 
@@ -115,8 +118,9 @@ Meteor.publishRelations('board', function(boardId) {
     parentCards.selector = (_ids) => ({ parentId: _ids });
     const boards = this.join(Boards);
     const subCards = this.join(Cards);
+    subCards.selector = (_ids) => ({ archived: isArchived });
 
-    this.cursor(Cards.find({ boardId: {$in: [boardId,  board.subtasksDefaultBoardId]}}), function(cardId, card) {
+    this.cursor(Cards.find({ boardId: {$in: [boardId,  board.subtasksDefaultBoardId]}, archived: isArchived }), function(cardId, card) {
       if (card.type === 'cardType-linkedCard') {
         const impCardId = card.linkedId;
         subCards.push(impCardId);

+ 1 - 1
server/publications/fast-render.js

@@ -5,5 +5,5 @@ FastRender.onAllRoutes(function() {
 });
 
 FastRender.route('/b/:id/:slug', function({ id }) {
-  this.subscribe('board', id);
+  this.subscribe('board', id, false);
 });