Explorar o código

Collapse Lists to be per user, not per board. In Progress.

Related #5388

Thanks to xet7 !
Lauri Ojansivu hai 1 ano
pai
achega
902f86d363

+ 7 - 7
client/components/lists/listHeader.jade

@@ -6,15 +6,15 @@ template(name="listHeader")
       +editListTitleForm
     else
       unless isMiniScreen
-        if collapsed
-          a.js-collapse(title="{{_ 'uncollapse'}}")
+        if listCollapsed
+          a.js-collapse-list(title="{{_ 'uncollapse'}}")
             i.fa.fa-arrow-left.list-header-uncollapse-left
             i.fa.fa-arrow-right.list-header-uncollapse-right
       if isMiniScreen
         if currentList
           a.list-header-left-icon.fa.fa-angle-left.js-unselect-list
       unless isMiniScreen
-        if collapsed
+        if listCollapsed
           if showCardsCountForList cards.length
             br
             span.cardCount {{cardsCount}}
@@ -29,7 +29,7 @@ template(name="listHeader")
            span(class="{{#if exceededWipLimit}}highlight{{/if}}") {{cards.length}}
            |/#{wipLimit.value})
       unless isMiniScreen
-        div(class="{{#if collapsed}}list-rotated{{/if}}")
+        div(class="{{#if listCollapsed}}list-rotated{{/if}}")
           h2.list-header-name(
             title="{{ moment modifiedAt 'LLL' }}"
             class="{{#if currentUser.isBoardMember}}{{#unless currentUser.isCommentOnly}}{{#unless currentUser.isWorker}}js-open-inlined-form is-editable{{/unless}}{{/unless}}{{/if}}")
@@ -39,7 +39,7 @@ template(name="listHeader")
              | (
              span(class="{{#if exceededWipLimit}}highlight{{/if}}") {{cards.length}}
              |/#{wipLimit.value})
-        unless collapsed
+        unless listCollapsed
           if showCardsCountForList cards.length
             span.cardCount {{cardsCount}} {{cardsCountForListIsOne cards.length}}
       if isMiniScreen
@@ -57,14 +57,14 @@ template(name="listHeader")
       else if currentUser.isBoardMember
         if isWatching
           i.list-header-watch-icon.fa.fa-eye
-        unless collapsed
+        unless listCollapsed
           div.list-header-menu
             unless currentUser.isCommentOnly
               //if isBoardAdmin
               //  a.fa.js-list-star.list-header-plus-top(class="fa-star{{#unless starred}}-o{{/unless}}")
               if canSeeAddCard
                 a.js-add-card.fa.fa-plus.list-header-plus-top(title="{{_ 'add-card-to-top-of-list'}}")
-                a.js-collapse(title="{{_ 'collapse'}}")
+                a.js-collapse-list(title="{{_ 'collapse'}}")
                   i.fa.fa-arrow-right.list-header-collapse-right
                   i.fa.fa-arrow-left.list-header-collapse-left
                 a.fa.fa-navicon.js-open-list-menu(title="{{_ 'listActionPopup-title'}}")

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

@@ -31,14 +31,14 @@ BlazeComponent.extendComponent({
       return !status;
     }
   },
-  collapsed(check = undefined) {
-    const list = Template.currentData();
-    const status = list.isCollapsed();
+  listCollapsed(check = undefined) {
+    const user = Meteor.user();
+    const status = user.hasCollapsedList(this._id);
     if (check === undefined) {
       // just check
       return status;
     } else {
-      list.collapse(!status);
+      user.toggleCollapseList(this._id);
       return !status;
     }
   },
@@ -115,9 +115,9 @@ BlazeComponent.extendComponent({
           event.preventDefault();
           this.starred(!this.starred());
         },
-        'click .js-collapse'(event) {
+        'click .js-collapse-list'(event) {
           event.preventDefault();
-          this.collapsed(!this.collapsed());
+          this.listCollapsed(!this.listCollapsed());
         },
         'click .js-open-list-menu': Popup.open('listAction'),
         'click .js-add-card.list-header-plus-top'(event) {

+ 0 - 14
models/lists.js

@@ -156,13 +156,6 @@ Lists.attachSchema(
       type: String,
       defaultValue: 'list',
     },
-    collapsed: {
-      /**
-       * is the list collapsed
-       */
-      type: Boolean,
-      defaultValue: false,
-    },
   }),
 );
 
@@ -293,10 +286,6 @@ Lists.helpers({
     return this.starred === true;
   },
 
-  isCollapsed() {
-    return this.collapsed === true;
-  },
-
   absoluteUrl() {
     const card = ReactiveCache.getCard({ listId: this._id });
     return card && card.absoluteUrl();
@@ -317,9 +306,6 @@ Lists.mutations({
   star(enable = true) {
     return { $set: { starred: !!enable } };
   },
-  collapse(enable = true) {
-    return { $set: { collapsed: !!enable } };
-  },
 
   archive() {
     if (this.isTemplateList()) {

+ 0 - 15
models/swimlanes.js

@@ -107,13 +107,6 @@ Swimlanes.attachSchema(
       type: String,
       defaultValue: 'swimlane',
     },
-    collapsed: {
-      /**
-       * is the swimlane collapsed
-       */
-      type: Boolean,
-      defaultValue: false,
-    },
   }),
 );
 
@@ -239,10 +232,6 @@ Swimlanes.helpers({
     return ret;
   },
 
-  isCollapsed() {
-    return this.collapsed === true;
-  },
-
   board() {
     return ReactiveCache.getBoard(this.boardId);
   },
@@ -285,10 +274,6 @@ Swimlanes.mutations({
     return { $set: { title } };
   },
 
-  collapse(enable = true) {
-    return { $set: { collapsed: !!enable } };
-  },
-
   archive() {
     if (this.isTemplateSwimlane()) {
       this.myLists().forEach(list => {

+ 60 - 0
models/users.js

@@ -440,6 +440,20 @@ Users.attachSchema(
       defaultValue: {},
       blackbox: true,
     },
+    'profile.listCollapsed': {
+      /**
+       * User-specific list of collapsed list IDs
+       */
+      type: [String],
+      optional: true,
+    },
+    'profile.swimlaneCollapsed': {
+      /**
+       * User-specific list of collapsed swimlane IDs
+       */
+      type: [String],
+      optional: true,
+    },
     services: {
       /**
        * services field of the user
@@ -736,6 +750,36 @@ Users.helpers({
     return _.contains(starredBoards, boardId);
   },
 
+  collapsedLists() {
+    const { collapsedLists = [] } = this.profile || {};
+    return Lists.userLists(
+      this._id,
+      false,
+      { _id: { $in: collapsedLists } },
+      { sort: { sort: 1 } },
+    );
+  },
+
+  hasCollapsedList(listId) {
+    const { collapsedLists = [] } = this.profile || {};
+    return _.contains(collapsedLists, listId);
+  },
+
+  collapsedSwimlanes() {
+    const { collapsedSwimlanes = [] } = this.profile || {};
+    return Swimlanes.userSwimlanes(
+      this._id,
+      false,
+      { _id: { $in: collapsedSwimlanes } },
+      { sort: { sort: 1 } },
+    );
+  },
+
+  hasCollapsedSwimlane(swimlaneId) {
+    const { collapsedSwimlanes = [] } = this.profile || {};
+    return _.contains(collapsedSwimlanes, swimlaneId);
+  },
+
   invitedBoards() {
     const { invitedBoards = [] } = this.profile || {};
     return Boards.userBoards(
@@ -1004,6 +1048,22 @@ Users.mutations({
       },
     };
   },
+  toggleCollapseList(listId) {
+    const queryKind = this.hasCollapsedList(listId) ? '$pull' : '$addToSet';
+    return {
+      [queryKind]: {
+        'profile.listCollapsed': listId,
+      },
+    };
+  },
+  toggleCollapseSwimlane(swimlaneId) {
+    const queryKind = this.hasCollapsedSwimlane(swimlaneId) ? '$pull' : '$addToSet';
+    return {
+      [queryKind]: {
+        'profile.swimlaneCollapsed': swimlaneId,
+      },
+    };
+  },
 
   addInvite(boardId) {
     return {

+ 0 - 1
server/publications/boards.js

@@ -61,7 +61,6 @@ Meteor.publishRelations('boards', function() {
               title: 1,
               boardId: 1,
               archived: 1,
-              collapsed: 1,
               sort: 1
             }
           },

+ 1 - 1
server/publications/cards.js

@@ -785,7 +785,7 @@ function findCards(sessionId, query) {
       ),
       ReactiveCache.getSwimlanes(
         { _id: { $in: swimlanes } },
-        { fields: { ...fields, color: 1, collapsed: 1 } },
+        { fields: { ...fields, color: 1 } },
         true,
       ),
       ReactiveCache.getLists({ _id: { $in: lists } }, { fields }, true),