Browse Source

Merge pull request #3419 from jrsupplee/master

My Cards add Due Date sort
Lauri Ojansivu 4 năm trước cách đây
mục cha
commit
1698b5cafb

+ 83 - 17
client/components/main/myCards.jade

@@ -1,9 +1,20 @@
 template(name="myCardsHeaderBar")
   h1
-    a.back-btn(href="{{pathFor 'home'}}")
-      i.fa.fa-chevron-left
+    //a.back-btn(href="{{pathFor 'home'}}")
+    //  i.fa.fa-chevron-left
     | {{_ 'my-cards'}}
 
+  .board-header-btns.left
+    a.board-header-btn.js-toggle-my-cards-choose-sort(title="{{_ 'my-cards-sort'}}")
+      //i.fa.fa-caret-down
+      i.fa.fa-sort
+      if $eq myCardsSort 'board'
+        i.fa.fa-th-large
+        | {{_ 'my-cards-sort-board'}}
+      if $eq myCardsSort 'dueAt'
+        i.fa.fa-calendar
+        | {{_ 'my-cards-sort-dueat'}}
+
 template(name="myCardsModalTitle")
   h2
     i.fa.fa-keyboard-o
@@ -11,20 +22,75 @@ template(name="myCardsModalTitle")
 
 template(name="myCards")
   .wrapper
-    each board in myBoards
-      .my-cards-board-wrapper
-        .board-title
-          +viewer
-            = board.title
-        each swimlane in board.mySwimlanes
-          .swimlane-title(class="{{#if swimlane.colorClass}}{{ swimlane.colorClass }}{{else}}swimlane-default-color{{/if}}")
+    if $eq myCardsSort 'board'
+      each board in myBoards
+        .my-cards-board-wrapper
+          .my-cards-board-title
             +viewer
-              = swimlane.title
-          each list in swimlane.myLists
-            .my-cards-list-wrapper
-              .list-title(class=list.colorClass)
+              = board.title
+          each swimlane in board.mySwimlanes
+            .my-cards-swimlane-title(class="{{#if swimlane.colorClass}}{{ swimlane.colorClass }}{{else}}swimlane-default-color{{/if}}")
+              +viewer
+                = swimlane.title
+            each list in swimlane.myLists
+              .my-cards-list-wrapper
+                .my-cards-list-title(class=list.colorClass)
+                  +viewer
+                    = list.title
+                each card in list.myCards
+                  .my-cards-card-wrapper
+                    a.minicard-wrapper(href=card.absoluteUrl)
+                      +minicard(card)
+    else
+      .my-cards-dueat-list-wrapper
+        each card in myCardsList
+          .my-cards-card-wrapper
+            a.minicard-wrapper.card-title(href=card.absoluteUrl)
+              +minicard(card)
+            ul.my-cards-context-list
+              li.my-cards-context(title="{{_ 'board'}}")
+                +viewer
+                  = card.board.title
+              li.my-cards-context.my-cards-context-separator
+                = ' '
+                | {{_ 'context-separator'}}
+                = ' '
+              li.my-cards-context(title="{{_ 'swimlane'}}")
+                +viewer
+                  = card.swimlane.title
+              li.my-cards-context
+                = ' '
+                | {{_ 'context-separator'}}
+                = ' '
+              li.my-cards-context(title="{{_ 'list'}}")
                 +viewer
-                  = list.title
-              each card in list.myCards
-                a.minicard-wrapper.card-title(href=card.absoluteUrl)
-                  +minicard(card)
+                  = card.list.title
+
+
+template(name="myCardsSortChangePopup")
+  ul.pop-over-list
+    li
+      with "my-cards-sort-board"
+        a.js-my-cards-sort-board
+          i.fa.fa-th-large.colorful
+          | {{_ 'my-cards-sort-board'}}
+          if $eq Utils.myCardsSort "board"
+            i.fa.fa-check
+    li
+      with "my-cards-sort-dueat"
+        a.js-my-cards-sort-dueat
+          i.fa.fa-calendar.colorful
+          | {{_ 'my-cards-sort-dueat'}}
+          if $eq Utils.myCardsSort "dueAt"
+            i.fa.fa-check
+
+//template(name="myCardsSortChangePopup")
+//  ul.pop-over-list
+//    li
+//      a.js-my-cards-sort-board
+//        i.fa.fa-th-large.colorful
+//        | {{_ 'my-cards-sort-board'}}
+//    li
+//      a.js-my-cards-sort-dueat
+//        i.fa.fa-calendar.colorful
+//        | {{_ 'my-cards-sort-dueat'}}

+ 101 - 28
client/components/main/myCards.js

@@ -1,22 +1,23 @@
-const subManager = new SubsManager();
-Meteor.subscribe('myCards');
-Meteor.subscribe('mySwimlanes');
-Meteor.subscribe('myLists');
-
-Template.myCardsHeaderBar.events({
-  'click .js-open-archived-board'() {
-    Modal.open('archivedBoards');
+BlazeComponent.extendComponent({
+  myCardsSort() {
+    // eslint-disable-next-line no-console
+    // console.log('sort:', Utils.myCardsSort());
+    return Utils.myCardsSort();
   },
-});
 
-Template.myCardsHeaderBar.helpers({
-  title() {
-    return FlowRouter.getRouteName() === 'home' ? 'my-boards' : 'public';
-  },
-  templatesUser() {
-    return Meteor.user();
+  events() {
+    return [
+      {
+        'click .js-toggle-my-cards-choose-sort'() {
+          // eslint-disable-next-line no-console
+          // console.log('open sort');
+          // Popup.open('myCardsSortChange');
+          Utils.myCardsSortToggle();
+        },
+      },
+    ];
   },
-});
+}).register('myCardsHeaderBar');
 
 Template.myCards.helpers({
   userId() {
@@ -24,10 +25,40 @@ Template.myCards.helpers({
   },
 });
 
+BlazeComponent.extendComponent({
+  events() {
+    return [
+      {
+        'click .js-my-cards-sort-board'() {
+          Utils.setMyCardsSort('board');
+          Popup.close();
+        },
+
+        'click .js-my-cards-sort-dueat'() {
+          Utils.setMyCardsSort('dueAt');
+          Popup.close();
+        },
+      },
+    ];
+  },
+}).register('myCardsSortChangePopup');
+
 BlazeComponent.extendComponent({
   onCreated() {
     Meteor.subscribe('setting');
-    // subManager.subscribe('myCards');
+    Meteor.subscribe('myCards');
+    Meteor.subscribe('mySwimlanes');
+    Meteor.subscribe('myLists');
+  },
+
+  myCardsSort() {
+    // eslint-disable-next-line no-console
+    console.log('sort:', Utils.myCardsSort());
+    return Utils.myCardsSort();
+  },
+
+  sortByBoard() {
+    return this.myCardsSort() === 'board';
   },
 
   myBoards() {
@@ -145,20 +176,62 @@ BlazeComponent.extendComponent({
     return boards;
   },
 
+  myCardsList() {
+    const userId = Meteor.userId();
+
+    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('cursor:', cursor);
+
+    const cards = [];
+    cursor.forEach(card => {
+      cards.push(card);
+    });
+
+    cards.sort((a, b) => {
+      const x = a.dueAt === null ? Date('2100-12-31') : a.dueAt;
+      const y = b.dueAt === null ? Date('2100-12-31') : b.dueAt;
+
+      if (x > y) return 1;
+      else if (x < y) return -1;
+
+      return 0;
+    });
+
+    // 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();
-        },
+        // '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();
+        // },
       },
     ];
   },

+ 27 - 34
client/components/main/myCards.styl

@@ -1,28 +1,7 @@
-.my-cards-list
-  .my-cards-list-item
-    border-bottom: 1px solid darken(white, 25%)
-    padding: 10px 5px
-
-    &:last-child
-      border-bottom: none
-
-    .my-cards-list-item-keys
-      margin-top: 5px
-      float: right
-
-      kbd
-        padding: 5px 8px
-        margin: 5px
-        font-size: 18px
-
-    .my-cards-list-item-action
-      font-size: 1.4em
-      margin: 5px
-
 .my-cards-board-wrapper
   border-radius: 8px
   //padding: 0.5rem
-  max-width: 400px
+  min-width: 400px
   border-width: 8px
   border-color: grey
   border-style: solid
@@ -30,14 +9,14 @@
   margin-right: auto
   margin-left: auto
 
-.board-title
+.my-cards-board-title
   font-size: 1.4rem
   font-weight: bold
   padding: 0.5rem
   background-color: grey
   color: white
 
-.swimlane-title
+.my-cards-swimlane-title
   font-size: 1.1rem
   font-weight: bold
   padding: 0.5rem
@@ -51,7 +30,7 @@
 .swimlane-default-color
   background-color: lightgrey
 
-.list-title
+.my-cards-list-title
   font-weight: bold
   font-size: 1.1rem
   //padding-bottom: 0
@@ -59,18 +38,32 @@
   text-align: center
   margin-bottom: 0.7rem
 
-.list-color-bar
-  //height: 0.3rem
-  margin-bottom: 0.3rem
-  margin-top: 0
-  padding-top: 0
-
 .my-cards-list-wrapper
   margin: 1rem
-  margin-top: 1rem
   border-radius: 5px
   padding: 1.5rem
   padding-top: 0.75rem
+  display: inline-block
+  min-width: 250px
+  max-width: 350px
+
+.my-cards-card-wrapper
+  margin-top: 0
+  margin-bottom: 10px
 
-.card-title
-  margin-top: 5px
+.my-cards-dueat-list-wrapper
+  max-width: 500px
+  margin-right: auto
+  margin-left: auto
+
+.my-cards-field-name
+  font-weight: bold
+
+.my-cards-context
+  display: inline-block
+
+.my-cards-context-separator
+  font-weight: bold
+
+.my-cards-context-list
+  margin-bottom: 0.7rem

+ 25 - 0
client/lib/utils.js

@@ -44,6 +44,31 @@ Utils = {
     }
   },
 
+  myCardsSort() {
+    let sort = window.localStorage.getItem('myCardsSort');
+
+    if (!sort || !['board', 'dueAt'].includes(sort)) {
+      window.localStorage.setItem('myCardsSort', 'board');
+      location.reload();
+      sort = 'board';
+    }
+
+    return sort;
+  },
+
+  myCardsSortToggle() {
+    if (this.myCardsSort() === 'board') {
+      this.setMyCardsSort('dueAt');
+    } else {
+      this.setMyCardsSort('board');
+    }
+  },
+
+  setMyCardsSort(sort) {
+    window.localStorage.setItem('myCardsSort', sort);
+    location.reload();
+  },
+
   // XXX We should remove these two methods
   goBoardId(_id) {
     const board = Boards.findOne(_id);

+ 5 - 1
i18n/en.i18n.json

@@ -852,5 +852,9 @@
   "my-cards": "My Cards",
   "card": "Card",
   "list": "List",
-  "board": "Board"
+  "board": "Board",
+  "context-separator": "/",
+  "my-cards-sort": "My Cards Sort",
+  "my-cards-sort-board": "By Board",
+  "my-cards-sort-dueat": "By Due Date"
 }