2
0
Эх сурвалжийг харах

Update Global Search, Due Cards, and My Cards to use the same
code for searching and display

John R. Supplee 4 жил өмнө
parent
commit
a1bda1169e

+ 10 - 6
client/components/main/dueCards.jade

@@ -22,13 +22,17 @@ template(name="dueCardsModalTitle")
 
 template(name="dueCards")
   if currentUser
-    if isPageReady.get
-      .wrapper
-        .due-cards-dueat-list-wrapper
-          each card in dueCardsList
-            +resultCard(card)
-    else
+    if searching.get
       +spinner
+    else if hasResults.get
+      .global-search-results-list-wrapper
+        if hasQueryErrors.get
+          div
+            each msg in errorMessages
+              span.global-search-error-messages
+                = msg
+        else
+          +resultsPaged(this)
 
 template(name="dueCardsViewChangePopup")
   if currentUser

+ 32 - 87
client/components/main/dueCards.js

@@ -1,3 +1,5 @@
+import { CardSearchPagedComponent } from '../../lib/cardSearch';
+
 const subManager = new SubsManager();
 
 BlazeComponent.extendComponent({
@@ -40,102 +42,43 @@ BlazeComponent.extendComponent({
   },
 }).register('dueCardsViewChangePopup');
 
-BlazeComponent.extendComponent({
+class DueCardsComponent extends CardSearchPagedComponent {
   onCreated() {
-    this.isPageReady = new ReactiveVar(false);
-
-    this.autorun(() => {
-      const handle = subManager.subscribe(
-        'dueCards',
-        Utils.dueCardsView() === 'all',
-      );
-      Tracker.nonreactive(() => {
-        Tracker.autorun(() => {
-          this.isPageReady.set(handle.ready());
-        });
-      });
-    });
-    Meteor.subscribe('setting');
-  },
+    super.onCreated();
+
+    const queryParams = {
+      has: [{ field: 'dueAt', exists: true }],
+      limit: 5,
+      skip: 0,
+      sort: { name: 'dueAt', order: 'des' },
+    };
+
+    if (Utils.dueCardsView() !== 'all') {
+      queryParams.users = [Meteor.user().username];
+    }
+
+    this.autorunGlobalSearch(queryParams);
+  }
 
   dueCardsView() {
     // eslint-disable-next-line no-console
     //console.log('sort:', Utils.dueCardsView());
     return Utils.dueCardsView();
-  },
+  }
 
   sortByBoard() {
     return this.dueCardsView() === 'board';
-  },
+  }
 
   dueCardsList() {
-    const allUsers = Utils.dueCardsView() === 'all';
-
-    const user = Meteor.user();
-
-    const archivedBoards = [];
-    Boards.find({ archived: true }).forEach(board => {
-      archivedBoards.push(board._id);
-    });
-
-    const permiitedBoards = [];
-    let selector = {
-      archived: false,
-    };
-    // for every user including admin allow her to see cards only from public boards
-    // or those where she is a member
-    //if (!user.isAdmin) {
-    selector.$or = [
-      { permission: 'public' },
-      { members: { $elemMatch: { userId: user._id, isActive: true } } },
-    ];
-    //}
-    Boards.find(selector).forEach(board => {
-      permiitedBoards.push(board._id);
-    });
-
-    const archivedSwimlanes = [];
-    Swimlanes.find({ archived: true }).forEach(swimlane => {
-      archivedSwimlanes.push(swimlane._id);
-    });
-
-    const archivedLists = [];
-    Lists.find({ archived: true }).forEach(list => {
-      archivedLists.push(list._id);
-    });
-
-    selector = {
-      archived: false,
-      boardId: {
-        $nin: archivedBoards,
-        $in: permiitedBoards,
-      },
-      swimlaneId: { $nin: archivedSwimlanes },
-      listId: { $nin: archivedLists },
-      dueAt: { $ne: null },
-      endAt: null,
-    };
-
-    if (!allUsers) {
-      selector.$or = [{ members: user._id }, { assignees: user._id }];
-    }
-
+    const results = this.getResults();
+    console.log('results:', results);
     const cards = [];
-
-    // eslint-disable-next-line no-console
-    // console.log('cards selector:', selector);
-    Cards.find(selector).forEach(card => {
-      cards.push(card);
-      // eslint-disable-next-line no-console
-      // console.log(
-      //   'board:',
-      //   card.board(),
-      //   'swimlane:',
-      //   card.swimlane(),
-      //   'list:',
-      //   card.list(),
-      // );
-    });
+    if (results) {
+      results.forEach(card => {
+        cards.push(card);
+      });
+    }
 
     cards.sort((a, b) => {
       const x = a.dueAt === null ? Date('2100-12-31') : a.dueAt;
@@ -148,7 +91,9 @@ BlazeComponent.extendComponent({
     });
 
     // eslint-disable-next-line no-console
-    // console.log('cards:', cards);
+    console.log('cards:', cards);
     return cards;
-  },
-}).register('dueCards');
+  }
+}
+
+DueCardsComponent.register('dueCards');

+ 18 - 15
client/components/main/globalSearch.jade

@@ -10,6 +10,23 @@ template(name="globalSearchModalTitle")
       i.fa.fa-keyboard-o
       | {{_ 'globalSearch-title'}}
 
+template(name="resultsPaged")
+  h1
+    = resultsHeading.get
+    a.fa.fa-link(title="{{_ 'link-to-search' }}" href="{{ getSearchHref }}")
+  each card in results.get
+    +resultCard(card)
+  table.global-search-footer
+    tr
+      td.global-search-previous-page
+        if hasPreviousPage.get
+          button.js-previous-page
+            | {{_ 'previous-page' }}
+      td.global-search-next-page(align="right")
+        if hasNextPage.get
+          button.js-next-page
+            | {{_ 'next-page' }}
+
 template(name="globalSearch")
   if currentUser
     .wrapper
@@ -32,21 +49,7 @@ template(name="globalSearch")
                 span.global-search-error-messages
                   = msg
           else
-            h1
-              = resultsHeading.get
-              a.fa.fa-link(title="{{_ 'link-to-search' }}" href="{{ getSearchHref }}")
-            each card in results.get
-              +resultCard(card)
-            table.global-search-footer
-              tr
-                td.global-search-previous-page
-                  if hasPreviousPage.get
-                    button.js-previous-page
-                      | {{_ 'previous-page' }}
-                td.global-search-next-page(align="right")
-                  if hasNextPage.get
-                    button.js-next-page
-                      | {{_ 'next-page' }}
+            +resultsPaged(this)
       else
         .global-search-page
           .global-search-help

+ 44 - 190
client/components/main/globalSearch.js

@@ -1,4 +1,6 @@
-const subManager = new SubsManager();
+import { CardSearchPagedComponent } from '../../lib/cardSearch';
+
+// const subManager = new SubsManager();
 
 BlazeComponent.extendComponent({
   events() {
@@ -34,27 +36,15 @@ BlazeComponent.extendComponent({
   },
 }).register('globalSearchViewChangePopup');
 
-BlazeComponent.extendComponent({
+class GlobalSearchComponent extends CardSearchPagedComponent {
   onCreated() {
-    this.searching = new ReactiveVar(false);
-    this.hasResults = new ReactiveVar(false);
-    this.hasQueryErrors = new ReactiveVar(false);
-    this.query = new ReactiveVar('');
-    this.resultsHeading = new ReactiveVar('');
-    this.searchLink = new ReactiveVar(null);
+    super.onCreated();
     this.myLists = new ReactiveVar([]);
     this.myLabelNames = new ReactiveVar([]);
     this.myBoardNames = new ReactiveVar([]);
-    this.results = new ReactiveVar([]);
-    this.hasNextPage = new ReactiveVar(false);
-    this.hasPreviousPage = new ReactiveVar(false);
-    this.queryParams = null;
     this.parsingErrors = [];
-    this.resultsCount = 0;
-    this.totalHits = 0;
-    this.queryErrors = null;
     this.colorMap = null;
-    this.resultsPerPage = 25;
+    this.queryParams = null;
 
     Meteor.call('myLists', (err, data) => {
       if (!err) {
@@ -73,7 +63,7 @@ BlazeComponent.extendComponent({
         this.myBoardNames.set(data);
       }
     });
-  },
+  }
 
   onRendered() {
     Meteor.subscribe('setting');
@@ -87,67 +77,19 @@ BlazeComponent.extendComponent({
     if (Session.get('globalQuery')) {
       this.searchAllBoards(Session.get('globalQuery'));
     }
-  },
+  }
 
   resetSearch() {
-    this.searching.set(false);
-    this.results.set([]);
-    this.hasResults.set(false);
-    this.hasQueryErrors.set(false);
-    this.resultsHeading.set('');
+    super.resetSearch();
     this.parsingErrors = [];
-    this.resultsCount = 0;
-    this.totalHits = 0;
-    this.queryErrors = null;
-  },
-
-  getSessionData() {
-    return SessionData.findOne({
-      userId: Meteor.userId(),
-      sessionId: SessionData.getSessionId(),
-    });
-  },
-
-  getResults() {
-    // eslint-disable-next-line no-console
-    // console.log('getting results');
-    if (this.queryParams) {
-      const sessionData = this.getSessionData();
-      // eslint-disable-next-line no-console
-      // console.log('selector:', sessionData.getSelector());
-      // console.log('session data:', sessionData);
-      const projection = sessionData.getProjection();
-      projection.skip = 0;
-      const cards = Cards.find({ _id: { $in: sessionData.cards } }, projection);
-      this.queryErrors = sessionData.errors;
-      if (this.queryErrors.length) {
-        this.hasQueryErrors.set(true);
-        return null;
-      }
-
-      if (cards) {
-        this.totalHits = sessionData.totalHits;
-        this.resultsCount = cards.count();
-        this.resultsStart = sessionData.lastHit - this.resultsCount + 1;
-        this.resultsEnd = sessionData.lastHit;
-        this.resultsHeading.set(this.getResultsHeading());
-        this.results.set(cards);
-        this.hasNextPage.set(sessionData.lastHit < sessionData.totalHits);
-        this.hasPreviousPage.set(
-          sessionData.lastHit - sessionData.resultsCount > 0,
-        );
-      }
-    }
-    this.resultsCount = 0;
-    return null;
-  },
+  }
 
   errorMessages() {
     if (this.parsingErrors.length) {
       return this.parsingErrorMessages();
     }
     return this.queryErrorMessages();
-  },
+  }
 
   parsingErrorMessages() {
     const messages = [];
@@ -159,21 +101,7 @@ BlazeComponent.extendComponent({
     }
 
     return messages;
-  },
-
-  queryErrorMessages() {
-    messages = [];
-
-    this.queryErrors.forEach(err => {
-      let value = err.color ? TAPi18n.__(`color-${err.value}`) : err.value;
-      if (!value) {
-        value = err.value;
-      }
-      messages.push(TAPi18n.__(err.tag, value));
-    });
-
-    return messages;
-  },
+  }
 
   searchAllBoards(query) {
     query = query.trim();
@@ -300,7 +228,7 @@ BlazeComponent.extendComponent({
 
     let text = '';
     while (query) {
-      m = query.match(reOperator1);
+      let m = query.match(reOperator1);
       if (!m) {
         m = query.match(reOperator2);
         if (m) {
@@ -326,7 +254,7 @@ BlazeComponent.extendComponent({
               // console.log('found color:', value);
             }
           } else if (['dueAt', 'createdAt', 'modifiedAt'].includes(operator)) {
-            let days = parseInt(value, 10);
+            const days = parseInt(value, 10);
             let duration = null;
             if (isNaN(days)) {
               // duration was specified as text
@@ -335,7 +263,8 @@ BlazeComponent.extendComponent({
                 let date = null;
                 switch (duration) {
                   case 'week':
-                    let week = moment().week();
+                    // eslint-disable-next-line no-case-declarations
+                    const week = moment().week();
                     if (week === 52) {
                       date = moment(1, 'W');
                       date.set('year', date.year() + 1);
@@ -344,7 +273,8 @@ BlazeComponent.extendComponent({
                     }
                     break;
                   case 'month':
-                    let month = moment().month();
+                    // eslint-disable-next-line no-case-declarations
+                    const month = moment().month();
                     // .month() is zero indexed
                     if (month === 11) {
                       date = moment(1, 'M');
@@ -354,7 +284,8 @@ BlazeComponent.extendComponent({
                     }
                     break;
                   case 'quarter':
-                    let quarter = moment().quarter();
+                    // eslint-disable-next-line no-case-declarations
+                    const quarter = moment().quarter();
                     if (quarter === 4) {
                       date = moment(1, 'Q');
                       date.set('year', date.year() + 1);
@@ -384,22 +315,20 @@ BlazeComponent.extendComponent({
                 });
                 value = null;
               }
+            } else if (operator === 'dueAt') {
+              value = {
+                operator: '$lt',
+                value: moment(moment().format('YYYY-MM-DD'))
+                  .add(days + 1, duration ? duration : 'days')
+                  .format(),
+              };
             } else {
-              if (operator === 'dueAt') {
-                value = {
-                  operator: '$lt',
-                  value: moment(moment().format('YYYY-MM-DD'))
-                    .add(days + 1, duration ? duration : 'days')
-                    .format(),
-                };
-              } else {
-                value = {
-                  operator: '$gte',
-                  value: moment(moment().format('YYYY-MM-DD'))
-                    .subtract(days, duration ? duration : 'days')
-                    .format(),
-                };
-              }
+              value = {
+                operator: '$gte',
+                value: moment(moment().format('YYYY-MM-DD'))
+                  .subtract(days, duration ? duration : 'days')
+                  .format(),
+              };
             }
           } else if (operator === 'sort') {
             let negated = false;
@@ -502,81 +431,11 @@ BlazeComponent.extendComponent({
       return;
     }
 
-    this.autorun(() => {
-      const handle = Meteor.subscribe(
-        'globalSearch',
-        SessionData.getSessionId(),
-        params,
-      );
-      Tracker.nonreactive(() => {
-        Tracker.autorun(() => {
-          if (handle.ready()) {
-            this.getResults();
-            this.searching.set(false);
-            this.hasResults.set(true);
-          }
-        });
-      });
-    });
-  },
-
-  nextPage() {
-    const sessionData = this.getSessionData();
-
-    this.autorun(() => {
-      const handle = Meteor.subscribe('nextPage', sessionData.sessionId);
-      Tracker.nonreactive(() => {
-        Tracker.autorun(() => {
-          if (handle.ready()) {
-            this.getResults();
-            this.searching.set(false);
-            this.hasResults.set(true);
-          }
-        });
-      });
-    });
-  },
-
-  previousPage() {
-    const sessionData = this.getSessionData();
-
-    this.autorun(() => {
-      const handle = Meteor.subscribe('previousPage', sessionData.sessionId);
-      Tracker.nonreactive(() => {
-        Tracker.autorun(() => {
-          if (handle.ready()) {
-            this.getResults();
-            this.searching.set(false);
-            this.hasResults.set(true);
-          }
-        });
-      });
-    });
-  },
-
-  getResultsHeading() {
-    if (this.resultsCount === 0) {
-      return TAPi18n.__('no-cards-found');
-    } else if (this.resultsCount === 1) {
-      return TAPi18n.__('one-card-found');
-    } else if (this.resultsCount === this.totalHits) {
-      return TAPi18n.__('n-cards-found', this.resultsCount);
-    }
-
-    return TAPi18n.__('n-n-of-n-cards-found', {
-      start: this.resultsStart,
-      end: this.resultsEnd,
-      total: this.totalHits,
-    });
-  },
-
-  getSearchHref() {
-    const baseUrl = window.location.href.replace(/([?#].*$|\s*$)/, '');
-    return `${baseUrl}?q=${encodeURIComponent(this.query.get())}`;
-  },
+    this.autorunGlobalSearch(params);
+  }
 
   searchInstructions() {
-    tags = {
+    const tags = {
       operator_board: TAPi18n.__('operator-board'),
       operator_list: TAPi18n.__('operator-list'),
       operator_swimlane: TAPi18n.__('operator-swimlane'),
@@ -654,7 +513,7 @@ BlazeComponent.extendComponent({
     [
       'globalSearch-instructions-operator-has',
       'globalSearch-instructions-operator-sort',
-      'globalSearch-instructions-operator-limit'
+      'globalSearch-instructions-operator-limit',
     ].forEach(instruction => {
       text += `\n* ${TAPi18n.__(instruction, tags)}`;
     });
@@ -672,7 +531,7 @@ BlazeComponent.extendComponent({
     });
 
     return text;
-  },
+  }
 
   labelColors() {
     return Boards.simpleSchema()._schema['labels.$.color'].allowedValues.map(
@@ -680,23 +539,16 @@ BlazeComponent.extendComponent({
         return { color, name: TAPi18n.__(`color-${color}`) };
       },
     );
-  },
+  }
 
   events() {
     return [
       {
+        ...super.events()[0],
         'submit .js-search-query-form'(evt) {
           evt.preventDefault();
           this.searchAllBoards(evt.target.searchQuery.value);
         },
-        'click .js-next-page'(evt) {
-          evt.preventDefault();
-          this.nextPage();
-        },
-        'click .js-previous-page'(evt) {
-          evt.preventDefault();
-          this.previousPage();
-        },
         'click .js-label-color'(evt) {
           evt.preventDefault();
           const input = document.getElementById('global-search-input');
@@ -739,5 +591,7 @@ BlazeComponent.extendComponent({
         },
       },
     ];
-  },
-}).register('globalSearch');
+  }
+}
+
+GlobalSearchComponent.register('globalSearch');

+ 4 - 4
client/components/main/myCards.jade

@@ -24,14 +24,16 @@ template(name="myCardsModalTitle")
 
 template(name="myCards")
   if currentUser
-    if isPageReady.get
+    if searching.get
+      +spinner
+    else
       .wrapper
         if $eq myCardsSort 'board'
           each board in myCardsList
             .my-cards-board-wrapper
               .my-cards-board-title(class=board.colorClass, id="header")
                 a(href=board.absoluteUrl)
-                  +viewer 
+                  +viewer
                     = board.title
               each swimlane in board.mySwimlanes
                 .my-cards-swimlane-title(class="{{#if swimlane.colorClass}}{{ swimlane.colorClass }}{{else}}swimlane-default-color{{/if}}")
@@ -50,8 +52,6 @@ template(name="myCards")
           .my-cards-dueat-list-wrapper
             each card in myDueCardsList
               +resultCard(card)
-    else
-      +spinner
 
 template(name="myCardsSortChangePopup")
   if currentUser

+ 100 - 153
client/components/main/myCards.js

@@ -1,3 +1,5 @@
+import {CardSearchPagedComponent} from "../../lib/cardSearch";
+
 const subManager = new SubsManager();
 
 BlazeComponent.extendComponent({
@@ -42,177 +44,139 @@ BlazeComponent.extendComponent({
   },
 }).register('myCardsSortChangePopup');
 
-BlazeComponent.extendComponent({
+class MyCardsComponent extends CardSearchPagedComponent {
   onCreated() {
-    this.isPageReady = new ReactiveVar(false);
+    super.onCreated();
 
-    this.autorun(() => {
-      const handle = subManager.subscribe('myCards');
-      Tracker.nonreactive(() => {
-        Tracker.autorun(() => {
-          this.isPageReady.set(handle.ready());
-        });
-      });
-    });
+    const queryParams = {
+      users: [Meteor.user().username],
+      sort: { name: 'dueAt', order: 'des' },
+    };
+
+    this.autorunGlobalSearch(queryParams);
     Meteor.subscribe('setting');
-  },
+  }
 
   myCardsSort() {
     // eslint-disable-next-line no-console
     //console.log('sort:', Utils.myCardsSort());
     return Utils.myCardsSort();
-  },
+  }
 
   sortByBoard() {
     return this.myCardsSort() === 'board';
-  },
+  }
 
   myCardsList() {
-    const userId = Meteor.userId();
     const boards = [];
     let board = null;
     let swimlane = null;
     let list = null;
 
-    const cursor = Cards.find(
-      {
-        $or: [{ members: userId }, { assignees: userId }],
-        archived: false,
-      },
-      {
-        sort: {
-          boardId: 1,
-          swimlaneId: 1,
-          listId: 1,
-          sort: 1,
-        },
-      },
-    );
+    const cursor = this.getResults();
 
-    let newBoard = false;
-    let newSwimlane = false;
-    let newList = false;
+    if (cursor) {
+      let newBoard = false;
+      let newSwimlane = false;
+      let newList = false;
 
-    cursor.forEach(card => {
-      // eslint-disable-next-line no-console
-      // console.log('card:', card.title);
-      if (list === null || card.listId !== list._id) {
+      cursor.forEach(card => {
         // eslint-disable-next-line no-console
-        // console.log('new list');
-        list = card.getList();
-        if (list.archived) {
-          list = null;
-          return;
+        // console.log('card:', card.title);
+        if (list === null || card.listId !== list._id) {
+          // eslint-disable-next-line no-console
+          // console.log('new list');
+          list = card.getList();
+          if (list.archived) {
+            list = null;
+            return;
+          }
+          list.myCards = [card];
+          newList = true;
         }
-        list.myCards = [card];
-        newList = true;
-      }
-      if (swimlane === null || card.swimlaneId !== swimlane._id) {
-        // eslint-disable-next-line no-console
-        // console.log('new swimlane');
-        swimlane = card.getSwimlane();
-        if (swimlane.archived) {
-          swimlane = null;
-          return;
+        if (swimlane === null || card.swimlaneId !== swimlane._id) {
+          // eslint-disable-next-line no-console
+          // console.log('new swimlane');
+          swimlane = card.getSwimlane();
+          if (swimlane.archived) {
+            swimlane = null;
+            return;
+          }
+          swimlane.myLists = [list];
+          newSwimlane = true;
         }
-        swimlane.myLists = [list];
-        newSwimlane = true;
-      }
-      if (board === null || card.boardId !== board._id) {
-        // eslint-disable-next-line no-console
-        // console.log('new board');
-        board = card.getBoard();
-        if (board.archived) {
-          board = null;
-          return;
+        if (board === null || card.boardId !== board._id) {
+          // eslint-disable-next-line no-console
+          // console.log('new board');
+          board = card.getBoard();
+          if (board.archived) {
+            board = null;
+            return;
+          }
+          // eslint-disable-next-line no-console
+          // console.log('board:', b, b._id, b.title);
+          board.mySwimlanes = [swimlane];
+          newBoard = true;
+        }
+
+        if (newBoard) {
+          boards.push(board);
+        } else if (newSwimlane) {
+          board.mySwimlanes.push(swimlane);
+        } else if (newList) {
+          swimlane.myLists.push(list);
+        } else {
+          list.myCards.push(card);
         }
-        // eslint-disable-next-line no-console
-        // console.log('board:', b, b._id, b.title);
-        board.mySwimlanes = [swimlane];
-        newBoard = true;
-      }
-
-      if (newBoard) {
-        boards.push(board);
-      } else if (newSwimlane) {
-        board.mySwimlanes.push(swimlane);
-      } else if (newList) {
-        swimlane.myLists.push(list);
-      } else {
-        list.myCards.push(card);
-      }
-
-      newBoard = false;
-      newSwimlane = false;
-      newList = false;
-    });
 
-    // sort the data structure
-    boards.forEach(board => {
-      board.mySwimlanes.forEach(swimlane => {
-        swimlane.myLists.forEach(list => {
-          list.myCards.sort((a, b) => {
+        newBoard = false;
+        newSwimlane = false;
+        newList = false;
+      });
+
+      // sort the data structure
+      boards.forEach(board => {
+        board.mySwimlanes.forEach(swimlane => {
+          swimlane.myLists.forEach(list => {
+            list.myCards.sort((a, b) => {
+              return a.sort - b.sort;
+            });
+          });
+          swimlane.myLists.sort((a, b) => {
             return a.sort - b.sort;
           });
         });
-        swimlane.myLists.sort((a, b) => {
+        board.mySwimlanes.sort((a, b) => {
           return a.sort - b.sort;
         });
       });
-      board.mySwimlanes.sort((a, b) => {
-        return a.sort - b.sort;
-      });
-    });
 
-    boards.sort((a, b) => {
-      let x = a.sort;
-      let y = b.sort;
-
-      // show the template board last
-      if (a.type === 'template-container') {
-        x = 99999999;
-      } else if (b.type === 'template-container') {
-        y = 99999999;
-      }
-      return x - y;
-    });
+      boards.sort((a, b) => {
+        let x = a.sort;
+        let y = b.sort;
 
-    // eslint-disable-next-line no-console
-    // console.log('boards:', boards);
-    return boards;
-  },
-
-  myDueCardsList() {
-    const userId = Meteor.userId();
+        // show the template board last
+        if (a.type === 'template-container') {
+          x = 99999999;
+        } else if (b.type === 'template-container') {
+          y = 99999999;
+        }
+        return x - y;
+      });
 
-    const cursor = Cards.find(
-      {
-        $or: [{ members: userId }, { assignees: userId }],
-        archived: false,
-      },
-      {
-        sort: {
-          dueAt: -1,
-          boardId: 1,
-          swimlaneId: 1,
-          listId: 1,
-          sort: 1,
-        },
-      },
-    );
+      // eslint-disable-next-line no-console
+      // console.log('boards:', boards);
+      return boards;
+    }
 
-    // eslint-disable-next-line no-console
-    // console.log('cursor:', cursor);
+    return [];
+  }
 
+  myDueCardsList() {
+    const cursor = this.getResults();
     const cards = [];
     cursor.forEach(card => {
-      if (
-        !card.getBoard().archived &&
-        !card.getSwimlane().archived &&
-        !card.getList().archived
-      ) {
-        cards.push(card);
-      }
+      cards.push(card);
     });
 
     cards.sort((a, b) => {
@@ -228,23 +192,6 @@ BlazeComponent.extendComponent({
     // eslint-disable-next-line no-console
     // console.log('cursor:', cards);
     return cards;
-  },
-
-  events() {
-    return [
-      {
-        // 'click .js-my-card'(evt) {
-        //   const card = this.currentData().card;
-        //   // eslint-disable-next-line no-console
-        //   console.log('currentData():', this.currentData());
-        //   // eslint-disable-next-line no-console
-        //   console.log('card:', card);
-        //   if (card) {
-        //     Utils.goCardId(card._id);
-        //   }
-        //   evt.preventDefault();
-        // },
-      },
-    ];
-  },
-}).register('myCards');
+  }
+}
+MyCardsComponent.register('myCards');

+ 61 - 185
server/publications/cards.js

@@ -5,175 +5,38 @@ Meteor.publish('card', cardId => {
   return Cards.find({ _id: cardId });
 });
 
-Meteor.publish('myCards', function() {
-  const userId = Meteor.userId();
-
-  const archivedBoards = [];
-  Boards.find({ archived: true }).forEach(board => {
-    archivedBoards.push(board._id);
-  });
-
-  const archivedSwimlanes = [];
-  Swimlanes.find({ archived: true }).forEach(swimlane => {
-    archivedSwimlanes.push(swimlane._id);
-  });
+Meteor.publish('myCards', function(sessionId) {
 
-  const archivedLists = [];
-  Lists.find({ archived: true }).forEach(list => {
-    archivedLists.push(list._id);
-  });
-
-  selector = {
-    archived: false,
-    boardId: { $nin: archivedBoards },
-    swimlaneId: { $nin: archivedSwimlanes },
-    listId: { $nin: archivedLists },
-    $or: [{ members: userId }, { assignees: userId }],
+  const queryParams = {
+    users: [Meteor.user().username],
+    // limit: 25,
+    skip: 0,
+    // sort: { name: 'dueAt', order: 'des' },
   };
 
-  const cards = Cards.find(selector, {
-    fields: {
-      _id: 1,
-      archived: 1,
-      boardId: 1,
-      swimlaneId: 1,
-      listId: 1,
-      title: 1,
-      type: 1,
-      sort: 1,
-      members: 1,
-      assignees: 1,
-      colors: 1,
-      dueAt: 1,
-    },
-  });
-
-  const boards = [];
-  const swimlanes = [];
-  const lists = [];
-  const users = [];
-
-  cards.forEach(card => {
-    if (card.boardId) boards.push(card.boardId);
-    if (card.swimlaneId) swimlanes.push(card.swimlaneId);
-    if (card.listId) lists.push(card.listId);
-    if (card.members) {
-      card.members.forEach(userId => {
-        users.push(userId);
-      });
-    }
-    if (card.assignees) {
-      card.assignees.forEach(userId => {
-        users.push(userId);
-      });
-    }
-  });
-
-  return [
-    cards,
-    Boards.find({ _id: { $in: boards } }),
-    Swimlanes.find({ _id: { $in: swimlanes } }),
-    Lists.find({ _id: { $in: lists } }),
-    Users.find({ _id: { $in: users } }, { fields: Users.safeFields }),
-  ];
+  return buildQuery(sessionId, queryParams);
 });
 
-Meteor.publish('dueCards', function(allUsers = false) {
-  check(allUsers, Boolean);
-
-  // eslint-disable-next-line no-console
-  // console.log('all users:', allUsers);
-
-  const user = Users.findOne({ _id: this.userId });
-
-  const archivedBoards = [];
-  Boards.find({ archived: true }).forEach(board => {
-    archivedBoards.push(board._id);
-  });
-
-  const permiitedBoards = [];
-  let selector = {
-    archived: false,
-  };
-
-  selector.$or = [
-    { permission: 'public' },
-    { members: { $elemMatch: { userId: user._id, isActive: true } } },
-  ];
-
-  Boards.find(selector).forEach(board => {
-    permiitedBoards.push(board._id);
-  });
-
-  const archivedSwimlanes = [];
-  Swimlanes.find({ archived: true }).forEach(swimlane => {
-    archivedSwimlanes.push(swimlane._id);
-  });
-
-  const archivedLists = [];
-  Lists.find({ archived: true }).forEach(list => {
-    archivedLists.push(list._id);
-  });
-
-  selector = {
-    archived: false,
-    boardId: { $nin: archivedBoards, $in: permiitedBoards },
-    swimlaneId: { $nin: archivedSwimlanes },
-    listId: { $nin: archivedLists },
-    dueAt: { $ne: null },
-    endAt: null,
-  };
-
-  if (!allUsers) {
-    selector.$or = [{ members: user._id }, { assignees: user._id }];
-  }
-
-  const cards = Cards.find(selector, {
-    fields: {
-      _id: 1,
-      archived: 1,
-      boardId: 1,
-      swimlaneId: 1,
-      listId: 1,
-      title: 1,
-      type: 1,
-      sort: 1,
-      members: 1,
-      assignees: 1,
-      colors: 1,
-      dueAt: 1,
-    },
-  });
-
-  const boards = [];
-  const swimlanes = [];
-  const lists = [];
-  const users = [];
-
-  cards.forEach(card => {
-    if (card.boardId) boards.push(card.boardId);
-    if (card.swimlaneId) swimlanes.push(card.swimlaneId);
-    if (card.listId) lists.push(card.listId);
-    if (card.members) {
-      card.members.forEach(userId => {
-        users.push(userId);
-      });
-    }
-    if (card.assignees) {
-      card.assignees.forEach(userId => {
-        users.push(userId);
-      });
-    }
-  });
-
-  return [
-    cards,
-    Boards.find({ _id: { $in: boards } }),
-    Swimlanes.find({ _id: { $in: swimlanes } }),
-    Lists.find({ _id: { $in: lists } }),
-    Users.find({ _id: { $in: users } }, { fields: Users.safeFields }),
-  ];
-});
+// Meteor.publish('dueCards', function(sessionId, allUsers = false) {
+//   check(sessionId, String);
+//   check(allUsers, Boolean);
+//
+//   // eslint-disable-next-line no-console
+//   // console.log('all users:', allUsers);
+//
+//   const queryParams = {
+//     has: [{ field: 'dueAt', exists: true }],
+//     limit: 25,
+//     skip: 0,
+//     sort: { name: 'dueAt', order: 'des' },
+//   };
+//
+//   if (!allUsers) {
+//     queryParams.users = [Meteor.user().username];
+//   }
+//
+//   return buildQuery(sessionId, queryParams);
+// });
 
 Meteor.publish('globalSearch', function(sessionId, queryParams) {
   check(sessionId, String);
@@ -182,9 +45,11 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
   // eslint-disable-next-line no-console
   // console.log('queryParams:', queryParams);
 
+  return buildQuery(sessionId, queryParams);
+});
+
+function buildQuery(sessionId, queryParams) {
   const userId = Meteor.userId();
-  // eslint-disable-next-line no-console
-  // console.log('userId:', userId);
 
   const errors = new (class {
     constructor() {
@@ -267,7 +132,7 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
 
     let archived = false;
     let endAt = null;
-    if (queryParams.status.length) {
+    if (queryParams.status && queryParams.status.length) {
       queryParams.status.forEach(status => {
         if (status === 'archived') {
           archived = true;
@@ -320,7 +185,7 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
       selector.endAt = endAt;
     }
 
-    if (queryParams.boards.length) {
+    if (queryParams.boards && queryParams.boards.length) {
       const queryBoards = [];
       queryParams.boards.forEach(query => {
         const boards = Boards.userSearch(userId, {
@@ -338,7 +203,7 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
       selector.boardId.$in = queryBoards;
     }
 
-    if (queryParams.swimlanes.length) {
+    if (queryParams.swimlanes && queryParams.swimlanes.length) {
       const querySwimlanes = [];
       queryParams.swimlanes.forEach(query => {
         const swimlanes = Swimlanes.find({
@@ -360,7 +225,7 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
       selector.swimlaneId.$in = querySwimlanes;
     }
 
-    if (queryParams.lists.length) {
+    if (queryParams.lists && queryParams.lists.length) {
       const queryLists = [];
       queryParams.lists.forEach(query => {
         const lists = Lists.find({
@@ -382,7 +247,7 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
       selector.listId.$in = queryLists;
     }
 
-    if (queryParams.comments.length) {
+    if (queryParams.comments && queryParams.comments.length) {
       const cardIds = CardComments.textSearch(userId, queryParams.comments).map(
         com => {
           return com.cardId;
@@ -398,15 +263,15 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
     ['dueAt', 'createdAt', 'modifiedAt'].forEach(field => {
       if (queryParams[field]) {
         selector[field] = {};
-        selector[field][queryParams[field]['operator']] = new Date(
-          queryParams[field]['value'],
+        selector[field][queryParams[field].operator] = new Date(
+          queryParams[field].value,
         );
       }
     });
 
     const queryMembers = [];
     const queryAssignees = [];
-    if (queryParams.users.length) {
+    if (queryParams.users && queryParams.users.length) {
       queryParams.users.forEach(query => {
         const users = Users.find({
           username: query,
@@ -422,7 +287,7 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
       });
     }
 
-    if (queryParams.members.length) {
+    if (queryParams.members && queryParams.members.length) {
       queryParams.members.forEach(query => {
         const users = Users.find({
           username: query,
@@ -437,7 +302,7 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
       });
     }
 
-    if (queryParams.assignees.length) {
+    if (queryParams.assignees && queryParams.assignees.length) {
       queryParams.assignees.forEach(query => {
         const users = Users.find({
           username: query,
@@ -465,7 +330,7 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
       selector.assignees = { $in: queryAssignees };
     }
 
-    if (queryParams.labels.length) {
+    if (queryParams.labels && queryParams.labels.length) {
       queryParams.labels.forEach(label => {
         const queryLabels = [];
 
@@ -516,16 +381,26 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
       });
     }
 
-    if (queryParams.has.length) {
+    if (queryParams.has && queryParams.has.length) {
       queryParams.has.forEach(has => {
         switch (has.field) {
           case 'attachment':
-            const attachments = Attachments.find({}, { fields: { cardId: 1 } });
-            selector.$and.push({ _id: { $in: attachments.map(a => a.cardId) } });
+            selector.$and.push({
+              _id: {
+                $in: Attachments.find({}, { fields: { cardId: 1 } }).map(
+                  a => a.cardId,
+                ),
+              },
+            });
             break;
           case 'checklist':
-            const checklists = Checklists.find({}, { fields: { cardId: 1 } });
-            selector.$and.push({ _id: { $in: checklists.map(a => a.cardId) } });
+            selector.$and.push({
+              _id: {
+                $in: Checklists.find({}, { fields: { cardId: 1 } }).map(
+                  a => a.cardId,
+                ),
+              },
+            });
             break;
           case 'description':
           case 'startAt':
@@ -677,7 +552,7 @@ Meteor.publish('globalSearch', function(sessionId, queryParams) {
   // console.log('projection:', projection);
 
   return findCards(sessionId, selector, projection, errors);
-});
+}
 
 Meteor.publish('brokenCards', function() {
   const user = Users.findOne({ _id: this.userId });
@@ -773,7 +648,8 @@ function findCards(sessionId, selector, projection, errors = null) {
   const userId = Meteor.userId();
 
   // eslint-disable-next-line no-console
-  // console.log('selector:', selector);
+  console.log('selector:', selector);
+  console.log('selector.$and:', selector.$and);
   // eslint-disable-next-line no-console
   // console.log('projection:', projection);
   let cards;
@@ -879,5 +755,5 @@ function findCards(sessionId, selector, projection, errors = null) {
     ];
   }
 
-  return [SessionData.find({ userId: userId, sessionId })];
+  return [SessionData.find({ userId, sessionId })];
 }