mirror of
https://github.com/wekan/wekan.git
synced 2025-12-16 23:40:13 +01:00
commit
5d6203f5f9
16 changed files with 477 additions and 102 deletions
|
|
@ -35,6 +35,37 @@ BlazeComponent.extendComponent({
|
||||||
this._isDragging = false;
|
this._isDragging = false;
|
||||||
// Used to set the overlay
|
// Used to set the overlay
|
||||||
this.mouseHasEnterCardDetails = false;
|
this.mouseHasEnterCardDetails = false;
|
||||||
|
|
||||||
|
// fix swimlanes sort field if there are null values
|
||||||
|
const currentBoardData = Boards.findOne(Session.get('currentBoard'));
|
||||||
|
const nullSortSwimlanes = currentBoardData.nullSortSwimlanes();
|
||||||
|
if (nullSortSwimlanes.count() > 0) {
|
||||||
|
const swimlanes = currentBoardData.swimlanes();
|
||||||
|
let count = 0;
|
||||||
|
swimlanes.forEach((s) => {
|
||||||
|
Swimlanes.update(s._id, {
|
||||||
|
$set: {
|
||||||
|
sort: count,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
count += 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// fix lists sort field if there are null values
|
||||||
|
const nullSortLists = currentBoardData.nullSortLists();
|
||||||
|
if (nullSortLists.count() > 0) {
|
||||||
|
const lists = currentBoardData.lists();
|
||||||
|
let count = 0;
|
||||||
|
lists.forEach((l) => {
|
||||||
|
Lists.update(l._id, {
|
||||||
|
$set: {
|
||||||
|
sort: count,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
count += 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onRendered() {
|
onRendered() {
|
||||||
const boardComponent = this;
|
const boardComponent = this;
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ BlazeComponent.extendComponent({
|
||||||
onCreated() {
|
onCreated() {
|
||||||
this.currentBoard = Boards.findOne(Session.get('currentBoard'));
|
this.currentBoard = Boards.findOne(Session.get('currentBoard'));
|
||||||
this.isLoaded = new ReactiveVar(false);
|
this.isLoaded = new ReactiveVar(false);
|
||||||
this.currentColor = new ReactiveVar(this.data().color);
|
|
||||||
const boardBody = this.parentComponent().parentComponent();
|
const boardBody = this.parentComponent().parentComponent();
|
||||||
//in Miniview parent is Board, not BoardBody.
|
//in Miniview parent is Board, not BoardBody.
|
||||||
if (boardBody !== null) {
|
if (boardBody !== null) {
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,6 @@
|
||||||
// });
|
// });
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
BlazeComponent.extendComponent({
|
||||||
onCreated() {
|
|
||||||
this.currentColor = new ReactiveVar(this.data().color);
|
|
||||||
},
|
|
||||||
|
|
||||||
template() {
|
template() {
|
||||||
return 'minicard';
|
return 'minicard';
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@
|
||||||
// transparent, because that won't work during a list drag.
|
// transparent, because that won't work during a list drag.
|
||||||
background: darken(white, 13%)
|
background: darken(white, 13%)
|
||||||
border-left: 1px solid darken(white, 20%)
|
border-left: 1px solid darken(white, 20%)
|
||||||
border-bottom: 1px solid #CCC
|
|
||||||
padding: 0
|
padding: 0
|
||||||
float: left
|
float: left
|
||||||
|
|
||||||
|
|
@ -44,12 +43,16 @@
|
||||||
background: white
|
background: white
|
||||||
margin: -3px 0 8px
|
margin: -3px 0 8px
|
||||||
|
|
||||||
|
.list-header-card-count
|
||||||
|
height: 35px
|
||||||
|
|
||||||
.list-header
|
.list-header
|
||||||
flex: 0 0 auto
|
flex: 0 0 auto
|
||||||
margin: 20px 12px 4px
|
padding: 20px 12px 4px
|
||||||
position: relative
|
position: relative
|
||||||
min-height: 20px
|
min-height: 20px
|
||||||
|
|
||||||
|
|
||||||
&.ui-sortable-handle
|
&.ui-sortable-handle
|
||||||
cursor: grab
|
cursor: grab
|
||||||
|
|
||||||
|
|
@ -68,16 +71,17 @@
|
||||||
text-overflow: ellipsis
|
text-overflow: ellipsis
|
||||||
word-wrap: break-word
|
word-wrap: break-word
|
||||||
|
|
||||||
|
|
||||||
.list-header-watch-icon
|
.list-header-watch-icon
|
||||||
padding-left: 10px
|
padding-left: 10px
|
||||||
color: #a6a6a6
|
color: #a6a6a6
|
||||||
|
|
||||||
.list-header-menu
|
.list-header-menu
|
||||||
position: absolute
|
position: absolute
|
||||||
padding: 7px
|
padding: 27px 19px
|
||||||
margin-top: 1px
|
margin-top: 1px
|
||||||
top: -@padding
|
top: -7px
|
||||||
right: -@padding
|
right: -7px
|
||||||
|
|
||||||
.list-header-plus-icon
|
.list-header-plus-icon
|
||||||
color: #a6a6a6
|
color: #a6a6a6
|
||||||
|
|
@ -198,3 +202,84 @@
|
||||||
.search-card-results
|
.search-card-results
|
||||||
max-height: 250px
|
max-height: 250px
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
|
|
||||||
|
list-header-color(background, color...)
|
||||||
|
background: background !important
|
||||||
|
if color
|
||||||
|
color: color !important //overwrite text for better visibility
|
||||||
|
|
||||||
|
.list-header-white
|
||||||
|
list-header-color(#ffffff, #4d4d4d) //Black text for better visibility
|
||||||
|
border: 1px solid #eee
|
||||||
|
|
||||||
|
.list-header-green
|
||||||
|
list-header-color(#3cb500, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.list-header-yellow
|
||||||
|
list-header-color(#fad900, #4d4d4d) //Black text for better visibility
|
||||||
|
|
||||||
|
.list-header-orange
|
||||||
|
list-header-color(#ff9f19, #4d4d4d) //Black text for better visibility
|
||||||
|
|
||||||
|
.list-header-red
|
||||||
|
list-header-color(#eb4646, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.list-header-purple
|
||||||
|
list-header-color(#a632db, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.list-header-blue
|
||||||
|
list-header-color(#0079bf, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.list-header-pink
|
||||||
|
list-header-color(#ff78cb, #4d4d4d) //Black text for better visibility
|
||||||
|
|
||||||
|
.list-header-sky
|
||||||
|
list-header-color(#00c2e0, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.list-header-black
|
||||||
|
list-header-color(#4d4d4d, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.list-header-lime
|
||||||
|
list-header-color(#51e898, #4d4d4d) //Black text for better visibility
|
||||||
|
|
||||||
|
.list-header-silver
|
||||||
|
list-header-color(unset, #4d4d4d) //Black text for better visibility
|
||||||
|
|
||||||
|
.list-header-peachpuff
|
||||||
|
list-header-color(#ffdab9, #4d4d4d) //Black text for better visibility
|
||||||
|
|
||||||
|
.list-header-crimson
|
||||||
|
list-header-color(#dc143c, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.list-header-plum
|
||||||
|
list-header-color(#dda0dd, #4d4d4d) //Black text for better visibility
|
||||||
|
|
||||||
|
.list-header-darkgreen
|
||||||
|
list-header-color(#006400, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.list-header-slateblue
|
||||||
|
list-header-color(#6a5acd, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.list-header-magenta
|
||||||
|
list-header-color(#ff00ff, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.list-header-gold
|
||||||
|
list-header-color(#ffd700, #4d4d4d) //Black text for better visibility
|
||||||
|
|
||||||
|
.list-header-navy
|
||||||
|
list-header-color(#000080, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.list-header-gray
|
||||||
|
list-header-color(#808080, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.list-header-saddlebrown
|
||||||
|
list-header-color(#8b4513, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.list-header-paleturquoise
|
||||||
|
list-header-color(#afeeee, #4d4d4d) //Black text for better visibility
|
||||||
|
|
||||||
|
.list-header-mistyrose
|
||||||
|
list-header-color(#ffe4e1, #4d4d4d) //Black text for better visibility
|
||||||
|
|
||||||
|
.list-header-indigo
|
||||||
|
list-header-color(#4b0082, #ffffff) //White text for better visibility
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
template(name="listHeader")
|
template(name="listHeader")
|
||||||
.list-header.js-list-header
|
.list-header.js-list-header(
|
||||||
|
class="{{#if limitToShowCardsCount}}list-header-card-count{{/if}}"
|
||||||
|
class="{{#if colorClass}}list-header-{{colorClass}}{{/if}}")
|
||||||
+inlinedForm
|
+inlinedForm
|
||||||
+editListTitleForm
|
+editListTitleForm
|
||||||
else
|
else
|
||||||
|
|
@ -49,6 +51,9 @@ template(name="listActionPopup")
|
||||||
li: a.js-toggle-watch-list {{#if isWatching}}{{_ 'unwatch'}}{{else}}{{_ 'watch'}}{{/if}}
|
li: a.js-toggle-watch-list {{#if isWatching}}{{_ 'unwatch'}}{{else}}{{_ 'watch'}}{{/if}}
|
||||||
unless currentUser.isCommentOnly
|
unless currentUser.isCommentOnly
|
||||||
hr
|
hr
|
||||||
|
ul.pop-over-list
|
||||||
|
li: a.js-set-color-list {{_ 'set-color-list'}}
|
||||||
|
hr
|
||||||
ul.pop-over-list
|
ul.pop-over-list
|
||||||
if cards.count
|
if cards.count
|
||||||
li: a.js-select-cards {{_ 'list-select-cards'}}
|
li: a.js-select-cards {{_ 'list-select-cards'}}
|
||||||
|
|
@ -111,3 +116,12 @@ template(name="wipLimitErrorPopup")
|
||||||
p {{_ 'wipLimitErrorPopup-dialog-pt1'}}
|
p {{_ 'wipLimitErrorPopup-dialog-pt1'}}
|
||||||
p {{_ 'wipLimitErrorPopup-dialog-pt2'}}
|
p {{_ 'wipLimitErrorPopup-dialog-pt2'}}
|
||||||
button.full.js-back-view(type="submit") {{_ 'cancel'}}
|
button.full.js-back-view(type="submit") {{_ 'cancel'}}
|
||||||
|
|
||||||
|
template(name="setListColorPopup")
|
||||||
|
form.edit-label
|
||||||
|
.palette-colors: each colors
|
||||||
|
span.card-label.palette-color.js-palette-color(class="list-header-{{color}}")
|
||||||
|
if(isSelected color)
|
||||||
|
i.fa.fa-check
|
||||||
|
button.primary.confirm.js-submit {{_ 'save'}}
|
||||||
|
button.js-remove-color.negate.wide.right {{_ 'unset-color'}}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
let listsColors;
|
||||||
|
Meteor.startup(() => {
|
||||||
|
listsColors = Lists.simpleSchema()._schema.color.allowedValues;
|
||||||
|
});
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
BlazeComponent.extendComponent({
|
||||||
canSeeAddCard() {
|
canSeeAddCard() {
|
||||||
const list = Template.currentData();
|
const list = Template.currentData();
|
||||||
|
|
@ -72,6 +77,7 @@ Template.listActionPopup.helpers({
|
||||||
|
|
||||||
Template.listActionPopup.events({
|
Template.listActionPopup.events({
|
||||||
'click .js-list-subscribe' () {},
|
'click .js-list-subscribe' () {},
|
||||||
|
'click .js-set-color-list': Popup.open('setListColor'),
|
||||||
'click .js-select-cards' () {
|
'click .js-select-cards' () {
|
||||||
const cardIds = this.allCards().map((card) => card._id);
|
const cardIds = this.allCards().map((card) => card._id);
|
||||||
MultiSelection.add(cardIds);
|
MultiSelection.add(cardIds);
|
||||||
|
|
@ -154,3 +160,34 @@ Template.listMorePopup.events({
|
||||||
Utils.goBoardId(this.boardId);
|
Utils.goBoardId(this.boardId);
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
BlazeComponent.extendComponent({
|
||||||
|
onCreated() {
|
||||||
|
this.currentList = this.currentData();
|
||||||
|
this.currentColor = new ReactiveVar(this.currentList.color);
|
||||||
|
},
|
||||||
|
|
||||||
|
colors() {
|
||||||
|
return listsColors.map((color) => ({ color, name: '' }));
|
||||||
|
},
|
||||||
|
|
||||||
|
isSelected(color) {
|
||||||
|
return this.currentColor.get() === color;
|
||||||
|
},
|
||||||
|
|
||||||
|
events() {
|
||||||
|
return [{
|
||||||
|
'click .js-palette-color'() {
|
||||||
|
this.currentColor.set(this.currentData().color);
|
||||||
|
},
|
||||||
|
'click .js-submit' () {
|
||||||
|
this.currentList.setColor(this.currentColor.get());
|
||||||
|
Popup.close();
|
||||||
|
},
|
||||||
|
'click .js-remove-color'() {
|
||||||
|
this.currentList.setColor(null);
|
||||||
|
Popup.close();
|
||||||
|
},
|
||||||
|
}];
|
||||||
|
},
|
||||||
|
}).register('setListColorPopup');
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
template(name="swimlaneHeader")
|
template(name="swimlaneHeader")
|
||||||
.swimlane-header-wrap.js-swimlane-header
|
.swimlane-header-wrap.js-swimlane-header(class='{{#if colorClass}}swimlane-{{colorClass}}{{/if}}')
|
||||||
+inlinedForm
|
+inlinedForm
|
||||||
+editSwimlaneTitleForm
|
+editSwimlaneTitleForm
|
||||||
else
|
else
|
||||||
|
|
@ -8,6 +8,7 @@ template(name="swimlaneHeader")
|
||||||
= title
|
= title
|
||||||
.swimlane-header-menu
|
.swimlane-header-menu
|
||||||
unless currentUser.isCommentOnly
|
unless currentUser.isCommentOnly
|
||||||
|
a.fa.fa-plus.js-open-add-swimlane-menu.swimlane-header-plus-icon
|
||||||
a.fa.fa-navicon.js-open-swimlane-menu
|
a.fa.fa-navicon.js-open-swimlane-menu
|
||||||
|
|
||||||
template(name="editSwimlaneTitleForm")
|
template(name="editSwimlaneTitleForm")
|
||||||
|
|
@ -19,5 +20,25 @@ template(name="editSwimlaneTitleForm")
|
||||||
|
|
||||||
template(name="swimlaneActionPopup")
|
template(name="swimlaneActionPopup")
|
||||||
unless currentUser.isCommentOnly
|
unless currentUser.isCommentOnly
|
||||||
|
ul.pop-over-list
|
||||||
|
li: a.js-set-swimlane-color {{_ 'select-color'}}
|
||||||
|
hr
|
||||||
ul.pop-over-list
|
ul.pop-over-list
|
||||||
li: a.js-close-swimlane {{_ 'archive-swimlane'}}
|
li: a.js-close-swimlane {{_ 'archive-swimlane'}}
|
||||||
|
|
||||||
|
template(name="swimlaneAddPopup")
|
||||||
|
unless currentUser.isCommentOnly
|
||||||
|
form
|
||||||
|
input.swimlane-name-input.full-line(type="text" placeholder="{{_ 'add-swimlane'}}"
|
||||||
|
autocomplete="off" autofocus)
|
||||||
|
.edit-controls.clearfix
|
||||||
|
button.primary.confirm(type="submit") {{_ 'add'}}
|
||||||
|
|
||||||
|
template(name="setSwimlaneColorPopup")
|
||||||
|
form.edit-label
|
||||||
|
.palette-colors: each colors
|
||||||
|
span.card-label.palette-color.js-palette-color(class="card-details-{{color}}")
|
||||||
|
if(isSelected color)
|
||||||
|
i.fa.fa-check
|
||||||
|
button.primary.confirm.js-submit {{_ 'save'}}
|
||||||
|
button.js-remove-color.negate.wide.right {{_ 'unset-color'}}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
|
const { calculateIndexData } = Utils;
|
||||||
|
|
||||||
|
let swimlaneColors;
|
||||||
|
Meteor.startup(() => {
|
||||||
|
swimlaneColors = Swimlanes.simpleSchema()._schema.color.allowedValues;
|
||||||
|
});
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
BlazeComponent.extendComponent({
|
||||||
editTitle(evt) {
|
editTitle(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
|
|
@ -11,15 +18,82 @@ BlazeComponent.extendComponent({
|
||||||
events() {
|
events() {
|
||||||
return [{
|
return [{
|
||||||
'click .js-open-swimlane-menu': Popup.open('swimlaneAction'),
|
'click .js-open-swimlane-menu': Popup.open('swimlaneAction'),
|
||||||
|
'click .js-open-add-swimlane-menu': Popup.open('swimlaneAdd'),
|
||||||
submit: this.editTitle,
|
submit: this.editTitle,
|
||||||
}];
|
}];
|
||||||
},
|
},
|
||||||
}).register('swimlaneHeader');
|
}).register('swimlaneHeader');
|
||||||
|
|
||||||
Template.swimlaneActionPopup.events({
|
Template.swimlaneActionPopup.events({
|
||||||
|
'click .js-set-swimlane-color': Popup.open('setSwimlaneColor'),
|
||||||
'click .js-close-swimlane' (evt) {
|
'click .js-close-swimlane' (evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
this.archive();
|
this.archive();
|
||||||
Popup.close();
|
Popup.close();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
BlazeComponent.extendComponent({
|
||||||
|
onCreated() {
|
||||||
|
this.currentSwimlane = this.currentData();
|
||||||
|
},
|
||||||
|
|
||||||
|
events() {
|
||||||
|
return [{
|
||||||
|
submit(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
const currentBoard = Boards.findOne(Session.get('currentBoard'));
|
||||||
|
const nextSwimlane = currentBoard.nextSwimlane(this.currentSwimlane);
|
||||||
|
const titleInput = this.find('.swimlane-name-input');
|
||||||
|
const title = titleInput.value.trim();
|
||||||
|
const sortValue = calculateIndexData(this.currentSwimlane, nextSwimlane, 1);
|
||||||
|
|
||||||
|
if (title) {
|
||||||
|
Swimlanes.insert({
|
||||||
|
title,
|
||||||
|
boardId: Session.get('currentBoard'),
|
||||||
|
sort: sortValue.base,
|
||||||
|
});
|
||||||
|
|
||||||
|
titleInput.value = '';
|
||||||
|
titleInput.focus();
|
||||||
|
}
|
||||||
|
// XXX ideally, we should move the popup to the newly
|
||||||
|
// created swimlane so a user can add more than one swimlane
|
||||||
|
// with a minimum of interactions
|
||||||
|
Popup.close();
|
||||||
|
},
|
||||||
|
}];
|
||||||
|
},
|
||||||
|
}).register('swimlaneAddPopup');
|
||||||
|
|
||||||
|
BlazeComponent.extendComponent({
|
||||||
|
onCreated() {
|
||||||
|
this.currentSwimlane = this.currentData();
|
||||||
|
this.currentColor = new ReactiveVar(this.currentSwimlane.color);
|
||||||
|
},
|
||||||
|
|
||||||
|
colors() {
|
||||||
|
return swimlaneColors.map((color) => ({ color, name: '' }));
|
||||||
|
},
|
||||||
|
|
||||||
|
isSelected(color) {
|
||||||
|
return this.currentColor.get() === color;
|
||||||
|
},
|
||||||
|
|
||||||
|
events() {
|
||||||
|
return [{
|
||||||
|
'click .js-palette-color'() {
|
||||||
|
this.currentColor.set(this.currentData().color);
|
||||||
|
},
|
||||||
|
'click .js-submit' () {
|
||||||
|
this.currentSwimlane.setColor(this.currentColor.get());
|
||||||
|
Popup.close();
|
||||||
|
},
|
||||||
|
'click .js-remove-color'() {
|
||||||
|
this.currentSwimlane.setColor(null);
|
||||||
|
Popup.close();
|
||||||
|
},
|
||||||
|
}];
|
||||||
|
},
|
||||||
|
}).register('setSwimlaneColorPopup');
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,22 @@
|
||||||
template(name="swimlane")
|
template(name="swimlane")
|
||||||
.swimlane.js-lists.js-swimlane
|
.swimlane.js-lists.js-swimlane
|
||||||
+swimlaneHeader
|
+swimlaneHeader
|
||||||
if isMiniScreen
|
.swimlane.list-group.js-lists
|
||||||
if currentList
|
if isMiniScreen
|
||||||
+list(currentList)
|
if currentList
|
||||||
|
+list(currentList)
|
||||||
|
else
|
||||||
|
each currentBoard.lists
|
||||||
|
+miniList(this)
|
||||||
|
if currentUser.isBoardMember
|
||||||
|
+addListForm
|
||||||
else
|
else
|
||||||
each currentBoard.lists
|
each currentBoard.lists
|
||||||
+miniList(this)
|
+list(this)
|
||||||
|
if currentCardIsInThisList _id ../_id
|
||||||
|
+cardDetails(currentCard)
|
||||||
if currentUser.isBoardMember
|
if currentUser.isBoardMember
|
||||||
+addListForm
|
+addListForm
|
||||||
else
|
|
||||||
each currentBoard.lists
|
|
||||||
+list(this)
|
|
||||||
if currentCardIsInThisList _id ../_id
|
|
||||||
+cardDetails(currentCard)
|
|
||||||
if currentUser.isBoardMember
|
|
||||||
+addListAndSwimlaneForm
|
|
||||||
|
|
||||||
template(name="listsGroup")
|
template(name="listsGroup")
|
||||||
.swimlane.list-group.js-lists
|
.swimlane.list-group.js-lists
|
||||||
|
|
@ -35,31 +36,6 @@ template(name="listsGroup")
|
||||||
if currentUser.isBoardMember
|
if currentUser.isBoardMember
|
||||||
+addListForm
|
+addListForm
|
||||||
|
|
||||||
template(name="addListAndSwimlaneForm")
|
|
||||||
.list.list-composer.js-list-composer
|
|
||||||
.list-header
|
|
||||||
+inlinedForm(autoclose=false)
|
|
||||||
input.list-name-input.full-line(type="text" placeholder="{{_ 'add-list'}}"
|
|
||||||
autocomplete="off" autofocus)
|
|
||||||
.edit-controls.clearfix
|
|
||||||
button.primary.confirm(type="submit") {{_ 'save'}}
|
|
||||||
a.fa.fa-times-thin.js-close-inlined-form
|
|
||||||
else
|
|
||||||
a.open-list-composer.js-open-inlined-form
|
|
||||||
i.fa.fa-plus
|
|
||||||
| {{_ 'add-list'}}
|
|
||||||
.list-header
|
|
||||||
+inlinedForm(autoclose=false)
|
|
||||||
input.swimlane-name-input.full-line(type="text" placeholder="{{_ 'add-swimlane'}}"
|
|
||||||
autocomplete="off" autofocus)
|
|
||||||
.edit-controls.clearfix
|
|
||||||
button.primary.confirm(type="submit") {{_ 'save'}}
|
|
||||||
a.fa.fa-times-thin.js-close-inlined-form
|
|
||||||
else
|
|
||||||
a.open-list-composer.js-open-inlined-form
|
|
||||||
i.fa.fa-plus
|
|
||||||
| {{_ 'add-swimlane'}}
|
|
||||||
|
|
||||||
template(name="addListForm")
|
template(name="addListForm")
|
||||||
.list.list-composer.js-list-composer
|
.list.list-composer.js-list-composer
|
||||||
.list-header
|
.list-header
|
||||||
|
|
|
||||||
|
|
@ -175,48 +175,6 @@ BlazeComponent.extendComponent({
|
||||||
},
|
},
|
||||||
}).register('addListForm');
|
}).register('addListForm');
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
|
||||||
// Proxy
|
|
||||||
open() {
|
|
||||||
this.childComponents('inlinedForm')[0].open();
|
|
||||||
},
|
|
||||||
|
|
||||||
events() {
|
|
||||||
return [{
|
|
||||||
submit(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
let titleInput = this.find('.list-name-input');
|
|
||||||
if (titleInput) {
|
|
||||||
const title = titleInput.value.trim();
|
|
||||||
if (title) {
|
|
||||||
Lists.insert({
|
|
||||||
title,
|
|
||||||
boardId: Session.get('currentBoard'),
|
|
||||||
sort: $('.list').length,
|
|
||||||
});
|
|
||||||
|
|
||||||
titleInput.value = '';
|
|
||||||
titleInput.focus();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
titleInput = this.find('.swimlane-name-input');
|
|
||||||
const title = titleInput.value.trim();
|
|
||||||
if (title) {
|
|
||||||
Swimlanes.insert({
|
|
||||||
title,
|
|
||||||
boardId: Session.get('currentBoard'),
|
|
||||||
sort: $('.swimlane').length,
|
|
||||||
});
|
|
||||||
|
|
||||||
titleInput.value = '';
|
|
||||||
titleInput.focus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}];
|
|
||||||
},
|
|
||||||
}).register('addListAndSwimlaneForm');
|
|
||||||
|
|
||||||
Template.swimlane.helpers({
|
Template.swimlane.helpers({
|
||||||
canSeeAddList() {
|
canSeeAddList() {
|
||||||
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
|
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
// transparent, because that won't work during a swimlane drag.
|
// transparent, because that won't work during a swimlane drag.
|
||||||
background: darken(white, 13%)
|
background: darken(white, 13%)
|
||||||
display: flex
|
display: flex
|
||||||
flex-direction: row
|
flex-direction: column
|
||||||
overflow: 0;
|
overflow: 0;
|
||||||
max-height: 100%
|
max-height: 100%
|
||||||
|
|
||||||
|
|
@ -27,20 +27,15 @@
|
||||||
.swimlane-header-wrap
|
.swimlane-header-wrap
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex: 0 0 50px;
|
flex: 0 0 24px;
|
||||||
padding-bottom: 30px;
|
background-color: #ccc;
|
||||||
border-bottom: 1px solid #CCC
|
|
||||||
|
|
||||||
.swimlane-header
|
.swimlane-header
|
||||||
-ms-writing-mode: tb-rl;
|
|
||||||
writing-mode: vertical-rl;
|
|
||||||
transform: rotate(180deg);
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 50px;
|
padding: 5px 5px
|
||||||
margin-top: 50px;
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
min-height: 9px;
|
min-height: 9px;
|
||||||
width: 50px;
|
width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
-o-text-overflow: ellipsis;
|
-o-text-overflow: ellipsis;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
|
@ -49,7 +44,93 @@
|
||||||
|
|
||||||
.swimlane-header-menu
|
.swimlane-header-menu
|
||||||
position: absolute
|
position: absolute
|
||||||
padding: 20px 20px
|
padding: 5px 5px
|
||||||
|
|
||||||
|
.swimlane-header-plus-icon
|
||||||
|
margin-left: 5px
|
||||||
|
margin-right: 10px
|
||||||
|
|
||||||
.list-group
|
.list-group
|
||||||
|
flex-direction: row
|
||||||
height: 100%
|
height: 100%
|
||||||
|
|
||||||
|
swimlane-color(background, color...)
|
||||||
|
background: background !important
|
||||||
|
if color
|
||||||
|
color: color !important //overwrite text for better visibility
|
||||||
|
|
||||||
|
.swimlane-white
|
||||||
|
swimlane-color(#ffffff, #4d4d4d) //Black text for better visibility
|
||||||
|
border: 1px solid #eee
|
||||||
|
|
||||||
|
.swimlane-green
|
||||||
|
swimlane-color(#3cb500, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.swimlane-yellow
|
||||||
|
swimlane-color(#fad900, #4d4d4d) //Black text for better visibility
|
||||||
|
|
||||||
|
.swimlane-orange
|
||||||
|
swimlane-color(#ff9f19, #4d4d4d) //Black text for better visibility
|
||||||
|
|
||||||
|
.swimlane-red
|
||||||
|
swimlane-color(#eb4646, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.swimlane-purple
|
||||||
|
swimlane-color(#a632db, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.swimlane-blue
|
||||||
|
swimlane-color(#0079bf, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.swimlane-pink
|
||||||
|
swimlane-color(#ff78cb, #4d4d4d) //Black text for better visibility
|
||||||
|
|
||||||
|
.swimlane-sky
|
||||||
|
swimlane-color(#00c2e0, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.swimlane-black
|
||||||
|
swimlane-color(#4d4d4d, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.swimlane-lime
|
||||||
|
swimlane-color(#51e898, #4d4d4d) //Black text for better visibility
|
||||||
|
|
||||||
|
.swimlane-silver
|
||||||
|
swimlane-color(unset, #4d4d4d) //Black text for better visibility
|
||||||
|
|
||||||
|
.swimlane-peachpuff
|
||||||
|
swimlane-color(#ffdab9, #4d4d4d) //Black text for better visibility
|
||||||
|
|
||||||
|
.swimlane-crimson
|
||||||
|
swimlane-color(#dc143c, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.swimlane-plum
|
||||||
|
swimlane-color(#dda0dd, #4d4d4d) //Black text for better visibility
|
||||||
|
|
||||||
|
.swimlane-darkgreen
|
||||||
|
swimlane-color(#006400, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.swimlane-slateblue
|
||||||
|
swimlane-color(#6a5acd, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.swimlane-magenta
|
||||||
|
swimlane-color(#ff00ff, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.swimlane-gold
|
||||||
|
swimlane-color(#ffd700, #4d4d4d) //Black text for better visibility
|
||||||
|
|
||||||
|
.swimlane-navy
|
||||||
|
swimlane-color(#000080, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.swimlane-gray
|
||||||
|
swimlane-color(#808080, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.swimlane-saddlebrown
|
||||||
|
swimlane-color(#8b4513, #ffffff) //White text for better visibility
|
||||||
|
|
||||||
|
.swimlane-paleturquoise
|
||||||
|
swimlane-color(#afeeee, #4d4d4d) //Black text for better visibility
|
||||||
|
|
||||||
|
.swimlane-mistyrose
|
||||||
|
swimlane-color(#ffe4e1, #4d4d4d) //Black text for better visibility
|
||||||
|
|
||||||
|
.swimlane-indigo
|
||||||
|
swimlane-color(#4b0082, #ffffff) //White text for better visibility
|
||||||
|
|
|
||||||
|
|
@ -335,8 +335,10 @@
|
||||||
"list-archive-cards-pop": "This will remove all the cards in this list from the board. To view cards in Archive and bring them back to the board, click “Menu” > “Archive”.",
|
"list-archive-cards-pop": "This will remove all the cards in this list from the board. To view cards in Archive and bring them back to the board, click “Menu” > “Archive”.",
|
||||||
"list-move-cards": "Move all cards in this list",
|
"list-move-cards": "Move all cards in this list",
|
||||||
"list-select-cards": "Select all cards in this list",
|
"list-select-cards": "Select all cards in this list",
|
||||||
|
"set-color-list": "Set Color",
|
||||||
"listActionPopup-title": "List Actions",
|
"listActionPopup-title": "List Actions",
|
||||||
"swimlaneActionPopup-title": "Swimlane Actions",
|
"swimlaneActionPopup-title": "Swimlane Actions",
|
||||||
|
"swimlaneAddPopup-title": "Add a Swimlane below",
|
||||||
"listImportCardPopup-title": "Import a Trello card",
|
"listImportCardPopup-title": "Import a Trello card",
|
||||||
"listMorePopup-title": "More",
|
"listMorePopup-title": "More",
|
||||||
"link-list": "Link to this list",
|
"link-list": "Link to this list",
|
||||||
|
|
@ -519,6 +521,8 @@
|
||||||
"editCardEndDatePopup-title": "Change end date",
|
"editCardEndDatePopup-title": "Change end date",
|
||||||
"setCardColorPopup-title": "Set color",
|
"setCardColorPopup-title": "Set color",
|
||||||
"setCardActionsColorPopup-title": "Choose a color",
|
"setCardActionsColorPopup-title": "Choose a color",
|
||||||
|
"setSwimlaneColorPopup-title": "Choose a color",
|
||||||
|
"setListColorPopup-title": "Choose a color",
|
||||||
"assigned-by": "Assigned By",
|
"assigned-by": "Assigned By",
|
||||||
"requested-by": "Requested By",
|
"requested-by": "Requested By",
|
||||||
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
|
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
|
||||||
|
|
|
||||||
|
|
@ -347,10 +347,37 @@ Boards.helpers({
|
||||||
return Lists.find({ boardId: this._id, archived: false }, { sort: { sort: 1 } });
|
return Lists.find({ boardId: this._id, archived: false }, { sort: { sort: 1 } });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
nullSortLists() {
|
||||||
|
return Lists.find({
|
||||||
|
boardId: this._id,
|
||||||
|
archived: false,
|
||||||
|
sort: { $eq: null },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
swimlanes() {
|
swimlanes() {
|
||||||
return Swimlanes.find({ boardId: this._id, archived: false }, { sort: { sort: 1 } });
|
return Swimlanes.find({ boardId: this._id, archived: false }, { sort: { sort: 1 } });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
nextSwimlane(swimlane) {
|
||||||
|
return Swimlanes.findOne({
|
||||||
|
boardId: this._id,
|
||||||
|
archived: false,
|
||||||
|
sort: { $gte: swimlane.sort },
|
||||||
|
_id: { $ne: swimlane._id },
|
||||||
|
}, {
|
||||||
|
sort: { sort: 1 },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
nullSortSwimlanes() {
|
||||||
|
return Swimlanes.find({
|
||||||
|
boardId: this._id,
|
||||||
|
archived: false,
|
||||||
|
sort: { $eq: null },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
hasOvertimeCards(){
|
hasOvertimeCards(){
|
||||||
const card = Cards.findOne({isOvertime: true, boardId: this._id, archived: false} );
|
const card = Cards.findOne({isOvertime: true, boardId: this._id, archived: false} );
|
||||||
return card !== undefined;
|
return card !== undefined;
|
||||||
|
|
|
||||||
|
|
@ -1526,6 +1526,10 @@ if (Meteor.isServer) {
|
||||||
Authentication.checkUserId(req.userId);
|
Authentication.checkUserId(req.userId);
|
||||||
const paramBoardId = req.params.boardId;
|
const paramBoardId = req.params.boardId;
|
||||||
const paramListId = req.params.listId;
|
const paramListId = req.params.listId;
|
||||||
|
const currentCards = Cards.find({
|
||||||
|
listId: paramListId,
|
||||||
|
archived: false,
|
||||||
|
}, { sort: ['sort'] });
|
||||||
const check = Users.findOne({
|
const check = Users.findOne({
|
||||||
_id: req.body.authorId,
|
_id: req.body.authorId,
|
||||||
});
|
});
|
||||||
|
|
@ -1538,7 +1542,7 @@ if (Meteor.isServer) {
|
||||||
description: req.body.description,
|
description: req.body.description,
|
||||||
userId: req.body.authorId,
|
userId: req.body.authorId,
|
||||||
swimlaneId: req.body.swimlaneId,
|
swimlaneId: req.body.swimlaneId,
|
||||||
sort: 0,
|
sort: currentCards.count(),
|
||||||
members,
|
members,
|
||||||
});
|
});
|
||||||
JsonRoutes.sendResult(res, {
|
JsonRoutes.sendResult(res, {
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,21 @@ Lists.attachSchema(new SimpleSchema({
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
defaultValue: false,
|
defaultValue: false,
|
||||||
},
|
},
|
||||||
|
color: {
|
||||||
|
/**
|
||||||
|
* the color of the list
|
||||||
|
*/
|
||||||
|
type: String,
|
||||||
|
optional: true,
|
||||||
|
// silver is the default, so it is left out
|
||||||
|
allowedValues: [
|
||||||
|
'white', 'green', 'yellow', 'orange', 'red', 'purple',
|
||||||
|
'blue', 'sky', 'lime', 'pink', 'black',
|
||||||
|
'peachpuff', 'crimson', 'plum', 'darkgreen',
|
||||||
|
'slateblue', 'magenta', 'gold', 'navy', 'gray',
|
||||||
|
'saddlebrown', 'paleturquoise', 'mistyrose', 'indigo',
|
||||||
|
],
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Lists.allow({
|
Lists.allow({
|
||||||
|
|
@ -148,6 +163,12 @@ Lists.helpers({
|
||||||
return list.wipLimit[option] ? list.wipLimit[option] : 0; // Necessary check to avoid exceptions for the case where the doc doesn't have the wipLimit field yet set
|
return list.wipLimit[option] ? list.wipLimit[option] : 0; // Necessary check to avoid exceptions for the case where the doc doesn't have the wipLimit field yet set
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
colorClass() {
|
||||||
|
if (this.color)
|
||||||
|
return this.color;
|
||||||
|
return '';
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Lists.mutations({
|
Lists.mutations({
|
||||||
|
|
@ -174,6 +195,17 @@ Lists.mutations({
|
||||||
setWipLimit(limit) {
|
setWipLimit(limit) {
|
||||||
return { $set: { 'wipLimit.value': limit } };
|
return { $set: { 'wipLimit.value': limit } };
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setColor(newColor) {
|
||||||
|
if (newColor === 'silver') {
|
||||||
|
newColor = null;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
$set: {
|
||||||
|
color: newColor,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Meteor.methods({
|
Meteor.methods({
|
||||||
|
|
@ -314,9 +346,11 @@ if (Meteor.isServer) {
|
||||||
try {
|
try {
|
||||||
Authentication.checkUserId( req.userId);
|
Authentication.checkUserId( req.userId);
|
||||||
const paramBoardId = req.params.boardId;
|
const paramBoardId = req.params.boardId;
|
||||||
|
const board = Boards.findOne(paramBoardId);
|
||||||
const id = Lists.insert({
|
const id = Lists.insert({
|
||||||
title: req.body.title,
|
title: req.body.title,
|
||||||
boardId: paramBoardId,
|
boardId: paramBoardId,
|
||||||
|
sort: board.lists().count(),
|
||||||
});
|
});
|
||||||
JsonRoutes.sendResult(res, {
|
JsonRoutes.sendResult(res, {
|
||||||
code: 200,
|
code: 200,
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,21 @@ Swimlanes.attachSchema(new SimpleSchema({
|
||||||
// XXX We should probably provide a default
|
// XXX We should probably provide a default
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
|
color: {
|
||||||
|
/**
|
||||||
|
* the color of the swimlane
|
||||||
|
*/
|
||||||
|
type: String,
|
||||||
|
optional: true,
|
||||||
|
// silver is the default, so it is left out
|
||||||
|
allowedValues: [
|
||||||
|
'white', 'green', 'yellow', 'orange', 'red', 'purple',
|
||||||
|
'blue', 'sky', 'lime', 'pink', 'black',
|
||||||
|
'peachpuff', 'crimson', 'plum', 'darkgreen',
|
||||||
|
'slateblue', 'magenta', 'gold', 'navy', 'gray',
|
||||||
|
'saddlebrown', 'paleturquoise', 'mistyrose', 'indigo',
|
||||||
|
],
|
||||||
|
},
|
||||||
updatedAt: {
|
updatedAt: {
|
||||||
/**
|
/**
|
||||||
* when was the swimlane last edited
|
* when was the swimlane last edited
|
||||||
|
|
@ -93,6 +108,12 @@ Swimlanes.helpers({
|
||||||
board() {
|
board() {
|
||||||
return Boards.findOne(this.boardId);
|
return Boards.findOne(this.boardId);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
colorClass() {
|
||||||
|
if (this.color)
|
||||||
|
return this.color;
|
||||||
|
return '';
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Swimlanes.mutations({
|
Swimlanes.mutations({
|
||||||
|
|
@ -107,6 +128,17 @@ Swimlanes.mutations({
|
||||||
restore() {
|
restore() {
|
||||||
return { $set: { archived: false } };
|
return { $set: { archived: false } };
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setColor(newColor) {
|
||||||
|
if (newColor === 'silver') {
|
||||||
|
newColor = null;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
$set: {
|
||||||
|
color: newColor,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Swimlanes.hookOptions.after.update = { fetchPrevious: false };
|
Swimlanes.hookOptions.after.update = { fetchPrevious: false };
|
||||||
|
|
@ -224,9 +256,11 @@ if (Meteor.isServer) {
|
||||||
try {
|
try {
|
||||||
Authentication.checkUserId( req.userId);
|
Authentication.checkUserId( req.userId);
|
||||||
const paramBoardId = req.params.boardId;
|
const paramBoardId = req.params.boardId;
|
||||||
|
const board = Boards.findOne(paramBoardId);
|
||||||
const id = Swimlanes.insert({
|
const id = Swimlanes.insert({
|
||||||
title: req.body.title,
|
title: req.body.title,
|
||||||
boardId: paramBoardId,
|
boardId: paramBoardId,
|
||||||
|
sort: board.swimlanes().count(),
|
||||||
});
|
});
|
||||||
JsonRoutes.sendResult(res, {
|
JsonRoutes.sendResult(res, {
|
||||||
code: 200,
|
code: 200,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue