const subManager = new SubsManager ( ) ;
const { calculateIndex , enableClickOnTouch } = Utils ;
Renaissance
_,,ad8888888888bba,_
,ad88888I888888888888888ba,
,88888888I88888888888888888888a,
,d888888888I8888888888888888888888b,
d88888PP"""" ""YY88888888888888888888b,
,d88"'__,,--------,,,,.;ZZZY8888888888888,
,8IIl'" ;;l"ZZZIII8888888888,
,I88l;' ;lZZZZZ888III8888888,
,II88Zl;. ;llZZZZZ888888I888888,
,II888Zl;. .;;;;;lllZZZ888888I8888b
,II8888Z;; `;;;;;''llZZ8888888I8888,
II88888Z;' .;lZZZ8888888I888b
II88888Z; _,aaa, .,aaaaa,__.l;llZZZ88888888I888
II88888IZZZZZZZZZ, .ZZZZZZZZZZZZZZ;llZZ88888888I888,
II88888IZZ<'(@@>Z| |ZZZ<'(@@>ZZZZ;;llZZ888888888I88I
,II88888; `""" ;| |ZZ; `""" ;;llZ8888888888I888
II888888l `;; .;llZZ8888888888I888,
,II888888Z; ;;; .;;llZZZ8888888888I888I
III888888Zl; .., `;; ,;;lllZZZ88888888888I888
II88888888Z;;...;(_ _) ,;;;llZZZZ88888888888I888,
II88888888Zl;;;;;' `--'Z;. .,;;;;llZZZZ88888888888I888b
]I888888888Z;;;;' ";llllll;..;;;lllZZZZ88888888888I8888,
II888888888Zl.;;"Y88bd888P";;,..;lllZZZZZ88888888888I8888I
II8888888888Zl;.; `"PPP";;;,..;lllZZZZZZZ88888888888I88888
II888888888888Zl;;. `;;;l;;;;lllZZZZZZZZW88888888888I88888
`II8888888888888Zl;. ,;;lllZZZZZZZZWMZ88888888888I88888
II8888888888888888ZbaalllZZZZZZZZZWWMZZZ8888888888I888888,
`II88888888888888888b"WWZZZZZWWWMMZZZZZZI888888888I888888b
`II88888888888888888;ZZMMMMMMZZZZZZZZllI888888888I8888888
`II8888888888888888 `;lZZZZZZZZZZZlllll888888888I8888888,
II8888888888888888, `;lllZZZZllllll;;.Y88888888I8888888b,
,II8888888888888888b .;;lllllll;;;.;..88888888I88888888b,
II888888888888888PZI;. .`;;;.;;;..; ...88888888I8888888888,
II888888888888PZ;;';;. ;. .;. .;. .. Y8888888I88888888888b,
,II888888888PZ;;' `8888888I8888888888888b,
II888888888' 888888I8888888888888888
,II888888888 ,888888I8888888888888888
,d88888888888 d888888I8888888888ZZZZZZ
,ad888888888888I 8888888I8888ZZZZZZZZZZZZ
888888888888888' 888888IZZZZZZZZZZZZZZZZZ
8888888888P'8P' Y888ZZZZZZZZZZZZZZZZZZZZ
888888888, " ,ZZZZZZZZZZZZZZZZZZZZZZZ
8888888888, ,ZZZZZZZZZZZZZZZZZZZZZZZZZZ
888888888888a, _ ,ZZZZZZZZZZZZZZZZZZZZ88888888
888888888888888ba,_d' ,ZZZZZZZZZZZZZZZZZ8888888888888
8888888888888888888888bbbaaa,,,______,ZZZZZZZZZZZZZZZ88888888888888888
88888888888888888888888888888888888ZZZZZZZZZZZZZZZ88888888888888888888
8888888888888888888888888888888888ZZZZZZZZZZZZZZ8888888888888888888888
888888888888888888888888888888888ZZZZZZZZZZZZZZ88888888888888888888888
8888888888888888888888888888888ZZZZZZZZZZZZZZ8888888888888888888888888
88888888888888888888888888888ZZZZZZZZZZZZZZ888888888888888888888888888
8888888888888888888888888888ZZZZZZZZZZZZZZ88888888888888888 Normand 8
88888888888888888888888888ZZZZZZZZZZZZZZ8888888888888888888 Veilleux 8
8888888888888888888888888ZZZZZZZZZZZZZZ8888888888888888888888888888888
11 years ago
BlazeComponent . extendComponent ( {
onCreated ( ) {
this . isBoardReady = new ReactiveVar ( false ) ;
// The pattern we use to manually handle data loading is described here:
// https://kadira.io/academy/meteor-routing-guide/content/subscriptions-and-data-management/using-subs-manager
// XXX The boardId should be readed from some sort the component "props",
// unfortunatly, Blaze doesn't have this notion.
this . autorun ( ( ) => {
const currentBoardId = Session . get ( 'currentBoard' ) ;
if ( ! currentBoardId )
return ;
const handle = subManager . subscribe ( 'board' , currentBoardId ) ;
Tracker . nonreactive ( ( ) => {
Tracker . autorun ( ( ) => {
this . isBoardReady . set ( handle . ready ( ) ) ;
} ) ;
} ) ;
} ) ;
} ,
onlyShowCurrentCard ( ) {
return Utils . isMiniScreen ( ) && Session . get ( 'currentCard' ) ;
} ,
} ) . register ( 'board' ) ;
BlazeComponent . extendComponent ( {
onCreated ( ) {
this . showOverlay = new ReactiveVar ( false ) ;
this . draggingActive = new ReactiveVar ( false ) ;
this . _isDragging = false ;
// Used to set the overlay
this . mouseHasEnterCardDetails = false ;
} ,
onRendered ( ) {
const boardComponent = this ;
const $swimlanesDom = boardComponent . $ ( '.js-swimlanes' ) ;
$swimlanesDom . sortable ( {
tolerance : 'pointer' ,
appendTo : '.board-canvas' ,
helper : 'clone' ,
handle : '.js-swimlane-header' ,
items : '.js-swimlane:not(.placeholder)' ,
placeholder : 'swimlane placeholder' ,
distance : 7 ,
start ( evt , ui ) {
ui . placeholder . height ( ui . helper . height ( ) ) ;
EscapeActions . executeUpTo ( 'popup-close' ) ;
boardComponent . setIsDragging ( true ) ;
} ,
stop ( evt , ui ) {
// To attribute the new index number, we need to get the DOM element
// of the previous and the following card -- if any.
const prevSwimlaneDom = ui . item . prev ( '.js-swimlane' ) . get ( 0 ) ;
const nextSwimlaneDom = ui . item . next ( '.js-swimlane' ) . get ( 0 ) ;
const sortIndex = calculateIndex ( prevSwimlaneDom , nextSwimlaneDom , 1 ) ;
$swimlanesDom . sortable ( 'cancel' ) ;
const swimlaneDomElement = ui . item . get ( 0 ) ;
const swimlane = Blaze . getData ( swimlaneDomElement ) ;
Swimlanes . update ( swimlane . _id , {
$set : {
sort : sortIndex . base ,
} ,
} ) ;
boardComponent . setIsDragging ( false ) ;
} ,
} ) ;
Renaissance
_,,ad8888888888bba,_
,ad88888I888888888888888ba,
,88888888I88888888888888888888a,
,d888888888I8888888888888888888888b,
d88888PP"""" ""YY88888888888888888888b,
,d88"'__,,--------,,,,.;ZZZY8888888888888,
,8IIl'" ;;l"ZZZIII8888888888,
,I88l;' ;lZZZZZ888III8888888,
,II88Zl;. ;llZZZZZ888888I888888,
,II888Zl;. .;;;;;lllZZZ888888I8888b
,II8888Z;; `;;;;;''llZZ8888888I8888,
II88888Z;' .;lZZZ8888888I888b
II88888Z; _,aaa, .,aaaaa,__.l;llZZZ88888888I888
II88888IZZZZZZZZZ, .ZZZZZZZZZZZZZZ;llZZ88888888I888,
II88888IZZ<'(@@>Z| |ZZZ<'(@@>ZZZZ;;llZZ888888888I88I
,II88888; `""" ;| |ZZ; `""" ;;llZ8888888888I888
II888888l `;; .;llZZ8888888888I888,
,II888888Z; ;;; .;;llZZZ8888888888I888I
III888888Zl; .., `;; ,;;lllZZZ88888888888I888
II88888888Z;;...;(_ _) ,;;;llZZZZ88888888888I888,
II88888888Zl;;;;;' `--'Z;. .,;;;;llZZZZ88888888888I888b
]I888888888Z;;;;' ";llllll;..;;;lllZZZZ88888888888I8888,
II888888888Zl.;;"Y88bd888P";;,..;lllZZZZZ88888888888I8888I
II8888888888Zl;.; `"PPP";;;,..;lllZZZZZZZ88888888888I88888
II888888888888Zl;;. `;;;l;;;;lllZZZZZZZZW88888888888I88888
`II8888888888888Zl;. ,;;lllZZZZZZZZWMZ88888888888I88888
II8888888888888888ZbaalllZZZZZZZZZWWMZZZ8888888888I888888,
`II88888888888888888b"WWZZZZZWWWMMZZZZZZI888888888I888888b
`II88888888888888888;ZZMMMMMMZZZZZZZZllI888888888I8888888
`II8888888888888888 `;lZZZZZZZZZZZlllll888888888I8888888,
II8888888888888888, `;lllZZZZllllll;;.Y88888888I8888888b,
,II8888888888888888b .;;lllllll;;;.;..88888888I88888888b,
II888888888888888PZI;. .`;;;.;;;..; ...88888888I8888888888,
II888888888888PZ;;';;. ;. .;. .;. .. Y8888888I88888888888b,
,II888888888PZ;;' `8888888I8888888888888b,
II888888888' 888888I8888888888888888
,II888888888 ,888888I8888888888888888
,d88888888888 d888888I8888888888ZZZZZZ
,ad888888888888I 8888888I8888ZZZZZZZZZZZZ
888888888888888' 888888IZZZZZZZZZZZZZZZZZ
8888888888P'8P' Y888ZZZZZZZZZZZZZZZZZZZZ
888888888, " ,ZZZZZZZZZZZZZZZZZZZZZZZ
8888888888, ,ZZZZZZZZZZZZZZZZZZZZZZZZZZ
888888888888a, _ ,ZZZZZZZZZZZZZZZZZZZZ88888888
888888888888888ba,_d' ,ZZZZZZZZZZZZZZZZZ8888888888888
8888888888888888888888bbbaaa,,,______,ZZZZZZZZZZZZZZZ88888888888888888
88888888888888888888888888888888888ZZZZZZZZZZZZZZZ88888888888888888888
8888888888888888888888888888888888ZZZZZZZZZZZZZZ8888888888888888888888
888888888888888888888888888888888ZZZZZZZZZZZZZZ88888888888888888888888
8888888888888888888888888888888ZZZZZZZZZZZZZZ8888888888888888888888888
88888888888888888888888888888ZZZZZZZZZZZZZZ888888888888888888888888888
8888888888888888888888888888ZZZZZZZZZZZZZZ88888888888888888 Normand 8
88888888888888888888888888ZZZZZZZZZZZZZZ8888888888888888888 Veilleux 8
8888888888888888888888888ZZZZZZZZZZZZZZ8888888888888888888888888888888
11 years ago
// ugly touch event hotfix
$ ( '.js-swimlane:not(.placeholder)' ) . each ( function ( ) {
enableClickOnTouch ( this ) ;
} ) ;
function userIsMember ( ) {
return Meteor . user ( ) && Meteor . user ( ) . isBoardMember ( ) && ! Meteor . user ( ) . isCommentOnly ( ) ;
}
// If there is no data in the board (ie, no lists) we autofocus the list
// creation form by clicking on the corresponding element.
const currentBoard = Boards . findOne ( Session . get ( 'currentBoard' ) ) ;
if ( userIsMember ( ) && currentBoard . lists ( ) . count ( ) === 0 ) {
boardComponent . openNewListForm ( ) ;
}
} ,
isViewSwimlanes ( ) {
const currentUser = Meteor . user ( ) ;
if ( ! currentUser ) return false ;
return ( currentUser . profile . boardView === 'board-view-swimlanes' ) ;
} ,
isViewLists ( ) {
const currentUser = Meteor . user ( ) ;
if ( ! currentUser ) return true ;
return ( currentUser . profile . boardView === 'board-view-lists' ) ;
} ,
isViewCalendar ( ) {
const currentUser = Meteor . user ( ) ;
if ( ! currentUser ) return true ;
return ( currentUser . profile . boardView === 'board-view-cal' ) ;
} ,
openNewListForm ( ) {
if ( this . isViewSwimlanes ( ) ) {
this . childComponents ( 'swimlane' ) [ 0 ]
. childComponents ( 'addListAndSwimlaneForm' ) [ 0 ] . open ( ) ;
} else if ( this . isViewLists ( ) ) {
this . childComponents ( 'listsGroup' ) [ 0 ]
. childComponents ( 'addListForm' ) [ 0 ] . open ( ) ;
}
} ,
events ( ) {
return [ {
// XXX The board-overlay div should probably be moved to the parent
// component.
'mouseenter .board-overlay' ( ) {
if ( this . mouseHasEnterCardDetails ) {
this . showOverlay . set ( false ) ;
}
} ,
'mouseup' ( ) {
if ( this . _isDragging ) {
this . _isDragging = false ;
}
} ,
} ] ;
} ,
// XXX Flow components allow us to avoid creating these two setter methods by
// exposing a public API to modify the component state. We need to investigate
// best practices here.
setIsDragging ( bool ) {
this . draggingActive . set ( bool ) ;
} ,
scrollLeft ( position = 0 ) {
const swimlanes = this . $ ( '.js-swimlanes' ) ;
swimlanes && swimlanes . animate ( {
scrollLeft : position ,
} ) ;
} ,
} ) . register ( 'boardBody' ) ;
BlazeComponent . extendComponent ( {
onRendered ( ) {
this . autorun ( function ( ) {
$ ( '#calendar-view' ) . fullCalendar ( 'refetchEvents' ) ;
} ) ;
} ,
calendarOptions ( ) {
return {
id : 'calendar-view' ,
defaultView : 'agendaDay' ,
editable : true ,
timezone : 'local' ,
header : {
left : 'title today prev,next' ,
center : 'agendaDay,listDay,timelineDay agendaWeek,listWeek,timelineWeek month,timelineMonth timelineYear' ,
right : '' ,
} ,
// height: 'parent', nope, doesn't work as the parent might be small
height : 'auto' ,
/* TODO: lists as resources: https://fullcalendar.io/docs/vertical-resource-view */
navLinks : true ,
nowIndicator : true ,
businessHours : {
// days of week. an array of zero-based day of week integers (0=Sunday)
dow : [ 1 , 2 , 3 , 4 , 5 ] , // Monday - Friday
start : '8:00' ,
end : '18:00' ,
} ,
locale : TAPi18n . getLanguage ( ) ,
events ( start , end , timezone , callback ) {
const currentBoard = Boards . findOne ( Session . get ( 'currentBoard' ) ) ;
const events = [ ] ;
currentBoard . cardsInInterval ( start . toDate ( ) , end . toDate ( ) ) . forEach ( function ( card ) {
events . push ( {
id : card . _id ,
title : card . title ,
start : card . startAt ,
end : card . endAt ,
allDay : Math . abs ( card . endAt . getTime ( ) - card . startAt . getTime ( ) ) / 1000 === 24 * 3600 ,
url : FlowRouter . url ( 'card' , {
boardId : currentBoard . _id ,
slug : currentBoard . slug ,
cardId : card . _id ,
} ) ,
} ) ;
} ) ;
callback ( events ) ;
} ,
eventResize ( event , delta , revertFunc ) {
let isOk = false ;
const card = Cards . findOne ( event . id ) ;
if ( card ) {
card . setEnd ( event . end . toDate ( ) ) ;
isOk = true ;
}
if ( ! isOk ) {
revertFunc ( ) ;
}
} ,
eventDrop ( event , delta , revertFunc ) {
let isOk = false ;
const card = Cards . findOne ( event . id ) ;
if ( card ) {
// TODO: add a flag for allDay events
if ( ! event . allDay ) {
card . setStart ( event . start . toDate ( ) ) ;
card . setEnd ( event . end . toDate ( ) ) ;
isOk = true ;
}
}
if ( ! isOk ) {
revertFunc ( ) ;
}
} ,
} ;
} ,
} ) . register ( 'calendarView' ) ;