function initSorting ( items ) {
items . sortable ( {
tolerance : 'pointer' ,
helper : 'clone' ,
items : '.js-checklist-item:not(.placeholder)' ,
axis : 'y' ,
distance : 7 ,
placeholder : 'placeholder' ,
scroll : false ,
start ( evt , ui ) {
ui . placeholder . height ( ui . helper . height ( ) ) ;
EscapeActions . executeUpTo ( 'popup-close' ) ;
} ,
stop ( evt , ui ) {
const parent = ui . item . parents ( '.js-checklist-items' ) ;
const orderedItems = [ ] ;
parent . find ( '.js-checklist-item' ) . each ( function ( i , item ) {
const checklistItem = Blaze . getData ( item ) . item ;
orderedItems . push ( checklistItem . _id ) ;
} ) ;
items . sortable ( 'cancel' ) ;
const formerParent = ui . item . parents ( '.js-checklist-items' ) ;
let checklist = Blaze . getData ( parent . get ( 0 ) ) . checklist ;
const oldChecklist = Blaze . getData ( formerParent . get ( 0 ) ) . checklist ;
if ( oldChecklist . _id !== checklist . _id ) {
const currentItem = Blaze . getData ( ui . item . get ( 0 ) ) . item ;
for ( let i = 0 ; i < orderedItems . length ; i ++ ) {
let itemId = orderedItems [ i ] ;
if ( itemId !== currentItem . _id ) continue ;
checklist . addItem ( currentItem . title ) ;
checklist = Checklists . findOne ( { _id : checklist . _id } ) ;
itemId = checklist . _id + ( checklist . newItemIndex - 1 ) ;
if ( currentItem . finished ) {
checklist . finishItem ( itemId ) ;
}
orderedItems [ i ] = itemId ;
oldChecklist . removeItem ( currentItem . _id ) ;
}
}
checklist . sortItems ( orderedItems ) ;
} ,
} ) ;
}
Template . checklists . onRendered ( function ( ) {
const self = BlazeComponent . getComponentForElement ( this . firstNode ) ;
self . itemsDom = this . $ ( '.card-checklist-items' ) ;
initSorting ( self . itemsDom ) ;
self . itemsDom . mousedown ( function ( evt ) {
evt . stopPropagation ( ) ;
} ) ;
function userIsMember ( ) {
return Meteor . user ( ) && Meteor . user ( ) . isBoardMember ( ) ;
}
// Disable sorting if the current user is not a board member
self . autorun ( ( ) => {
const $itemsDom = $ ( self . itemsDom ) ;
if ( $itemsDom . data ( 'sortable' ) ) {
$ ( self . itemsDom ) . sortable ( 'option' , 'disabled' , ! userIsMember ( ) ) ;
}
} ) ;
} ) ;
BlazeComponent . extendComponent ( {
addChecklist ( event ) {
event . preventDefault ( ) ;
const textarea = this . find ( 'textarea.js-add-checklist-item' ) ;
const title = textarea . value . trim ( ) ;
const cardId = this . currentData ( ) . cardId ;
const card = Cards . findOne ( cardId ) ;
if ( title ) {
Checklists . insert ( {
cardId ,
title ,
sort : card . checklists ( ) . count ( ) ,
} ) ;
setTimeout ( ( ) => {
this . $ ( '.add-checklist-item' ) . last ( ) . click ( ) ;
} , 100 ) ;
}
textarea . value = '' ;
textarea . focus ( ) ;
} ,
addChecklistItem ( event ) {
event . preventDefault ( ) ;
const textarea = this . find ( 'textarea.js-add-checklist-item' ) ;
const title = textarea . value . trim ( ) ;
const checklist = this . currentData ( ) . checklist ;
if ( title ) {
checklist . addItem ( title ) ;
}
// We keep the form opened, empty it.
textarea . value = '' ;
textarea . focus ( ) ;
} ,
editChecklist ( event ) {
event . preventDefault ( ) ;
const textarea = this . find ( 'textarea.js-edit-checklist-item' ) ;
const title = textarea . value . trim ( ) ;
const checklist = this . currentData ( ) . checklist ;
checklist . setTitle ( title ) ;
} ,
canModifyCard ( ) {
return Meteor . user ( ) && Meteor . user ( ) . isBoardMember ( ) && ! Meteor . user ( ) . isCommentOnly ( ) ;
} ,
editChecklistItem ( event ) {
event . preventDefault ( ) ;
const textarea = this . find ( 'textarea.js-edit-checklist-item' ) ;
const title = textarea . value . trim ( ) ;
const itemId = this . currentData ( ) . item . _id ;
const checklist = this . currentData ( ) . checklist ;
checklist . editItem ( itemId , title ) ;
} ,
deleteItem ( ) {
const checklist = this . currentData ( ) . checklist ;
const item = this . currentData ( ) . item ;
if ( checklist && item && item . _id ) {
checklist . removeItem ( item . _id ) ;
}
} ,
deleteChecklist ( ) {
const checklist = this . currentData ( ) . checklist ;
if ( checklist && checklist . _id ) {
Checklists . remove ( checklist . _id ) ;
}
} ,
pressKey ( event ) {
//If user press enter key inside a form, submit it, so user doesn't have to leave keyboard to submit a form.
if ( event . keyCode === 13 ) {
event . preventDefault ( ) ;
const $form = $ ( event . currentTarget ) . closest ( 'form' ) ;
$form . find ( 'button[type=submit]' ) . click ( ) ;
}
} ,
events ( ) {
return [ {
'submit .js-add-checklist' : this . addChecklist ,
'submit .js-edit-checklist-title' : this . editChecklist ,
'submit .js-add-checklist-item' : this . addChecklistItem ,
'submit .js-edit-checklist-item' : this . editChecklistItem ,
'click .js-delete-checklist-item' : this . deleteItem ,
'click .js-delete-checklist' : this . deleteChecklist ,
keydown : this . pressKey ,
} ] ;
} ,
} ) . register ( 'checklists' ) ;
Template . itemDetail . helpers ( {
canModifyCard ( ) {
return Meteor . user ( ) && Meteor . user ( ) . isBoardMember ( ) && ! Meteor . user ( ) . isCommentOnly ( ) ;
} ,
} ) ;
BlazeComponent . extendComponent ( {
toggleItem ( ) {
const checklist = this . currentData ( ) . checklist ;
const item = this . currentData ( ) . item ;
if ( checklist && item && item . _id ) {
checklist . toggleItem ( item . _id ) ;
}
} ,
events ( ) {
return [ {
'click .item .check-box' : this . toggleItem ,
} ] ;
} ,
} ) . register ( 'itemDetail' ) ;