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

This commit is contained in:
amadilsons 2017-10-31 21:10:36 +00:00
parent 8bf3f300ad
commit fdd1aad80d
5 changed files with 70 additions and 36 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -49,23 +49,15 @@ Lists.attachSchema(new SimpleSchema({
'wipLimit.value': { 'wipLimit.value': {
type: Number, type: Number,
decimal: false, decimal: false,
autoValue() { defaultValue: 1,
if(this.isInsert){
return 0;
}
return this.value;
},
optional: true,
}, },
'wipLimit.enabled':{ 'wipLimit.enabled': {
type: Boolean, type: Boolean,
autoValue() { defaultValue: false,
if(this.isInsert){ },
return false; 'wipLimit.soft': {
} type: Boolean,
return this.value; defaultValue: false,
},
optional: true,
}, },
})); }));
@ -123,6 +115,10 @@ Lists.mutations({
return { $set: { archived: false } }; return { $set: { archived: false } };
}, },
toggleSoftLimit(toggle) {
return { $set: { 'wipLimit.soft': toggle } };
},
toggleWipLimit(toggle) { toggleWipLimit(toggle) {
return { $set: { 'wipLimit.enabled': toggle } }; return { $set: { 'wipLimit.enabled': toggle } };
}, },
@ -136,17 +132,25 @@ Meteor.methods({
applyWipLimit(listId, limit){ applyWipLimit(listId, limit){
check(listId, String); check(listId, String);
check(limit, Number); check(limit, Number);
if(limit === 0){
limit = 1;
}
Lists.findOne({ _id: listId }).setWipLimit(limit); Lists.findOne({ _id: listId }).setWipLimit(limit);
}, },
enableWipLimit(listId) { enableWipLimit(listId) {
check(listId, String); check(listId, String);
const list = Lists.findOne({ _id: listId }); 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 if(list.getWipLimit('value') === 0){
list.toggleWipLimit(!list.getWipLimit('enabled')); list.setWipLimit(1);
} else {
list.toggleWipLimit(true); // First time toggle is always to 'true' because default is 'false'
} }
list.toggleWipLimit(!list.getWipLimit('enabled'));
},
enableSoftLimit(listId) {
check(listId, String);
const list = Lists.findOne({ _id: listId });
list.toggleSoftLimit(!list.getWipLimit('soft'));
}, },
}); });