Răsfoiți Sursa

added soft wip limit feature, fixed wipLimit=0 bug (??)

amadilsons 7 ani în urmă
părinte
comite
fdd1aad80d

+ 9 - 0
client/components/lists/list.styl

@@ -79,6 +79,9 @@
   .list-header-plus-icon
     color: #a6a6a6
 
+  .highlight
+    color: #ce1414
+
 .list-body
   flex: 1
   display: flex
@@ -126,3 +129,9 @@
 
   .wip-limit-error
     display: none
+
+  .soft-wip-limit
+    margin-right: 8px
+
+  div
+    float: left

+ 1 - 2
client/components/lists/listBody.js

@@ -102,8 +102,7 @@ BlazeComponent.extendComponent({
 
   reachedWipLimit() {
     const list = Template.currentData();
-    if( !list.getWipLimit() ) { return false; }
-    return list.getWipLimit('enabled') && list.getWipLimit('value') === list.cards().count();
+    return !list.getWipLimit('soft') && list.getWipLimit('enabled') && list.getWipLimit('value') <= list.cards().count();
   },
 
   events() {

+ 11 - 5
client/components/lists/listHeader.jade

@@ -5,10 +5,12 @@ template(name="listHeader")
     else
       h2.list-header-name(
         class="{{#if currentUser.isBoardMember}}js-open-inlined-form is-editable{{/if}}")
-        = title
-        if isWipLimitEnabled
-          span
-            | ({{cards.count}}/#{wipLimit.value})
+        = title 
+        if wipLimit.enabled
+         |&nbsp;(
+         span(class="{{#if reachedWipLimit}}highlight{{/if}}") {{cards.count}}
+         |/#{wipLimit.value})
+        
         if showCardsCountForList cards.count
           = cards.count
           span.lowercase
@@ -18,7 +20,7 @@ template(name="listHeader")
           i.list-header-watch-icon.fa.fa-eye
         div.list-header-menu
           unless currentUser.isCommentOnly
-            unless isWipLimitEnabled
+            if canSeeAddCard
               a.js-add-card.fa.fa-plus.list-header-plus-icon
             a.fa.fa-navicon.js-open-list-menu
 
@@ -86,6 +88,10 @@ template(name="setWipLimitPopup")
         input.wip-limit-value(type="number" value="{{ wipLimitValue }}" min="1" max="99")
         input.wip-limit-apply(type="submit" value="{{_ 'apply'}}")
         input.wip-limit-error
+      p
+        .soft-wip-limit
+          .materialCheckBox(class="{{#if isWipLimitSoft}}is-checked{{/if}}")
+        label Soft Limit
         
 template(name="wipLimitErrorPopup")
   .wip-limit-invalid

+ 26 - 10
client/components/lists/listHeader.js

@@ -1,4 +1,9 @@
 BlazeComponent.extendComponent({
+  canSeeAddCard() {
+    const list = Template.currentData();
+    return !list.getWipLimit('enabled') || list.getWipLimit('soft') || !this.reachedWipLimit();
+  },
+
   editTitle(evt) {
     evt.preventDefault();
     const newTitle = this.childComponents('inlinedForm')[0].getValue().trim();
@@ -13,18 +18,15 @@ BlazeComponent.extendComponent({
     return list.findWatcher(Meteor.userId());
   },
 
-  isWipLimitEnabled() {
-    const wipLimit = this.currentData().getWipLimit();
-    if(!wipLimit) {
-      return 0;
-    }
-    return wipLimit.enabled && wipLimit.value > 0;
-  },
-
   limitToShowCardsCount() {
     return Meteor.user().getLimitToShowCardsCount();
   },
 
+  reachedWipLimit() {
+    const list = Template.currentData();
+    return list.getWipLimit('enabled') && list.getWipLimit('value') <= list.cards().count();
+  },
+
   showCardsCountForList(count) {
     return count > this.limitToShowCardsCount();
   },
@@ -82,7 +84,7 @@ BlazeComponent.extendComponent({
     const list = Template.currentData();
     const limit = parseInt(Template.instance().$('.wip-limit-value').val(), 10);
 
-    if(limit < list.cards().count()){
+    if(limit < list.cards().count() && !list.getWipLimit('soft')){
       Template.instance().$('.wip-limit-error').click();
     } else {
       Meteor.call('applyWipLimit', list._id, limit);
@@ -90,15 +92,28 @@ BlazeComponent.extendComponent({
     }
   },
 
+  enableSoftLimit() {
+    const list = Template.currentData();
+
+    if(list.getWipLimit('soft') && list.getWipLimit('value') < list.cards().count()){
+      list.setWipLimit(list.cards().count());
+    }
+    Meteor.call('enableSoftLimit', Template.currentData()._id);
+  },
+
   enableWipLimit() {
     const list = Template.currentData();
     // Prevent user from using previously stored wipLimit.value if it is less than the current number of cards in the list
-    if(list.getWipLimit() && !list.getWipLimit('enabled') && list.getWipLimit('value') < list.cards().count()){
+    if(!list.getWipLimit('enabled') && list.getWipLimit('value') < list.cards().count()){
       list.setWipLimit(list.cards().count());
     }
     Meteor.call('enableWipLimit', list._id);
   },
 
+  isWipLimitSoft() {
+    return Template.currentData().getWipLimit('soft');
+  },
+
   isWipLimitEnabled() {
     return Template.currentData().getWipLimit('enabled');
   },
@@ -112,6 +127,7 @@ BlazeComponent.extendComponent({
       'click .js-enable-wip-limit': this.enableWipLimit,
       'click .wip-limit-apply': this.applyWipLimit,
       'click .wip-limit-error': Popup.open('wipLimitError'),
+      'click .materialCheckBox': this.enableSoftLimit,
     }];
   },
 }).register('setWipLimitPopup');

+ 23 - 19
models/lists.js

@@ -49,23 +49,15 @@ Lists.attachSchema(new SimpleSchema({
   'wipLimit.value': {
     type: Number,
     decimal: false,
-    autoValue() {
-      if(this.isInsert){
-        return 0;
-      }
-      return this.value;
-    },
-    optional: true,
+    defaultValue: 1,
   },
-  'wipLimit.enabled':{
+  'wipLimit.enabled': {
     type: Boolean,
-    autoValue() {
-      if(this.isInsert){
-        return false;
-      }
-      return this.value;
-    },
-    optional: true,
+    defaultValue: false,
+  },
+  'wipLimit.soft': {
+    type: Boolean,
+    defaultValue: false,
   },
 }));
 
@@ -123,6 +115,10 @@ Lists.mutations({
     return { $set: { archived: false } };
   },
 
+  toggleSoftLimit(toggle) {
+    return { $set: { 'wipLimit.soft': toggle } };
+  },
+
   toggleWipLimit(toggle) {
     return { $set: { 'wipLimit.enabled': toggle } };
   },
@@ -136,17 +132,25 @@ Meteor.methods({
   applyWipLimit(listId, limit){
     check(listId, String);
     check(limit, Number);
+    if(limit === 0){
+      limit = 1;
+    }
     Lists.findOne({ _id: listId }).setWipLimit(limit);
   },
 
   enableWipLimit(listId) {
     check(listId, String);
     const list = Lists.findOne({ _id: listId });
-    if(list.getWipLimit()){ // Necessary check to avoid exceptions for the case where the doc doesn't have the wipLimit field yet set
-      list.toggleWipLimit(!list.getWipLimit('enabled'));
-    } else {
-      list.toggleWipLimit(true); // First time toggle is always to 'true' because default is 'false'
+    if(list.getWipLimit('value') === 0){
+      list.setWipLimit(1);
     }
+    list.toggleWipLimit(!list.getWipLimit('enabled'));
+  },
+
+  enableSoftLimit(listId) {
+    check(listId, String);
+    const list = Lists.findOne({ _id: listId });
+    list.toggleSoftLimit(!list.getWipLimit('soft'));
   },
 });