| 
									
										
										
										
											2016-02-10 05:59:46 -08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @provides javelin-workboard-column | 
					
						
							|  |  |  |  * @requires javelin-install | 
					
						
							|  |  |  |  *           javelin-workboard-card | 
					
						
							|  |  |  |  * @javelin | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | JX.install('WorkboardColumn', { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   construct: function(board, phid, root) { | 
					
						
							|  |  |  |     this._board = board; | 
					
						
							|  |  |  |     this._phid = phid; | 
					
						
							|  |  |  |     this._root = root; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-10 13:53:36 -08:00
										 |  |  |     this._panel = JX.DOM.findAbove(root, 'div', 'workpanel'); | 
					
						
							|  |  |  |     this._pointsNode = JX.DOM.find(this._panel, 'span', 'column-points'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     this._pointsContentNode = JX.DOM.find( | 
					
						
							|  |  |  |       this._panel, | 
					
						
							|  |  |  |       'span', | 
					
						
							|  |  |  |       'column-points-content'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-10 05:59:46 -08:00
										 |  |  |     this._cards = {}; | 
					
						
							|  |  |  |     this._naturalOrder = []; | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   members: { | 
					
						
							|  |  |  |     _phid: null, | 
					
						
							|  |  |  |     _root: null, | 
					
						
							|  |  |  |     _board: null, | 
					
						
							|  |  |  |     _cards: null, | 
					
						
							|  |  |  |     _naturalOrder: null, | 
					
						
							| 
									
										
										
										
											2016-02-10 13:53:36 -08:00
										 |  |  |     _panel: null, | 
					
						
							|  |  |  |     _pointsNode: null, | 
					
						
							|  |  |  |     _pointsContentNode: null, | 
					
						
							|  |  |  |     _dirty: true, | 
					
						
							| 
									
										
										
										
											2016-02-10 05:59:46 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     getPHID: function() { | 
					
						
							|  |  |  |       return this._phid; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     getRoot: function() { | 
					
						
							|  |  |  |       return this._root; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     getCards: function() { | 
					
						
							|  |  |  |       return this._cards; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     getCard: function(phid) { | 
					
						
							|  |  |  |       return this._cards[phid]; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     getBoard: function() { | 
					
						
							|  |  |  |       return this._board; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     setNaturalOrder: function(order) { | 
					
						
							|  |  |  |       this._naturalOrder = order; | 
					
						
							|  |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-10 13:53:36 -08:00
										 |  |  |     getPointsNode: function() { | 
					
						
							|  |  |  |       return this._pointsNode; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     getPointsContentNode: function() { | 
					
						
							|  |  |  |       return this._pointsContentNode; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     getWorkpanelNode: function() { | 
					
						
							|  |  |  |       return this._panel; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-10 05:59:46 -08:00
										 |  |  |     newCard: function(phid) { | 
					
						
							|  |  |  |       var card = new JX.WorkboardCard(this, phid); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       this._cards[phid] = card; | 
					
						
							|  |  |  |       this._naturalOrder.push(phid); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return card; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     removeCard: function(phid) { | 
					
						
							|  |  |  |       var card = this._cards[phid]; | 
					
						
							|  |  |  |       delete this._cards[phid]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       for (var ii = 0; ii < this._naturalOrder.length; ii++) { | 
					
						
							|  |  |  |         if (this._naturalOrder[ii] == phid) { | 
					
						
							|  |  |  |           this._naturalOrder.splice(ii, 1); | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return card; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     addCard: function(card, after) { | 
					
						
							|  |  |  |       var phid = card.getPHID(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       card.setColumn(this); | 
					
						
							|  |  |  |       this._cards[phid] = card; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var index = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (after) { | 
					
						
							|  |  |  |         for (var ii = 0; ii < this._naturalOrder.length; ii++) { | 
					
						
							|  |  |  |           if (this._naturalOrder[ii] == after) { | 
					
						
							|  |  |  |             index = ii + 1; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (index > this._naturalOrder.length) { | 
					
						
							|  |  |  |         this._naturalOrder.push(phid); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         this._naturalOrder.splice(index, 0, phid); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     getCardNodes: function() { | 
					
						
							|  |  |  |       var cards = this.getCards(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var nodes = []; | 
					
						
							|  |  |  |       for (var k in cards) { | 
					
						
							|  |  |  |         nodes.push(cards[k].getNode()); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return nodes; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     getCardPHIDs: function() { | 
					
						
							|  |  |  |       return JX.keys(this.getCards()); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-10 13:53:36 -08:00
										 |  |  |     getPointLimit: function() { | 
					
						
							|  |  |  |       return JX.Stratcom.getData(this.getRoot()).pointLimit; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     markForRedraw: function() { | 
					
						
							|  |  |  |       this._dirty = true; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     isMarkedForRedraw: function() { | 
					
						
							|  |  |  |       return this._dirty; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-10 05:59:46 -08:00
										 |  |  |     redraw: function() { | 
					
						
							| 
									
										
										
										
											2016-02-10 13:53:36 -08:00
										 |  |  |       var board = this.getBoard(); | 
					
						
							|  |  |  |       var order = board.getOrder(); | 
					
						
							| 
									
										
										
										
											2016-02-10 05:59:46 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       var list; | 
					
						
							|  |  |  |       if (order == 'natural') { | 
					
						
							|  |  |  |         list = this._getCardsSortedNaturally(); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         list = this._getCardsSortedByKey(order); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var content = []; | 
					
						
							|  |  |  |       for (var ii = 0; ii < list.length; ii++) { | 
					
						
							| 
									
										
										
										
											2016-02-10 13:53:36 -08:00
										 |  |  |         var card = list[ii]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         var node = card.getNode(); | 
					
						
							| 
									
										
										
										
											2016-02-10 05:59:46 -08:00
										 |  |  |         content.push(node); | 
					
						
							| 
									
										
										
										
											2016-02-10 13:53:36 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-10 05:59:46 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       JX.DOM.setContent(this.getRoot(), content); | 
					
						
							| 
									
										
										
										
											2016-02-10 13:53:36 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       this._redrawFrame(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       this._dirty = false; | 
					
						
							| 
									
										
										
										
											2016-02-10 05:59:46 -08:00
										 |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _getCardsSortedNaturally: function() { | 
					
						
							|  |  |  |       var list = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       for (var ii = 0; ii < this._naturalOrder.length; ii++) { | 
					
						
							|  |  |  |         var phid = this._naturalOrder[ii]; | 
					
						
							|  |  |  |         list.push(this.getCard(phid)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return list; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _getCardsSortedByKey: function(order) { | 
					
						
							|  |  |  |       var cards = this.getCards(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var list = []; | 
					
						
							|  |  |  |       for (var k in cards) { | 
					
						
							|  |  |  |         list.push(cards[k]); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       list.sort(JX.bind(this, this._sortCards, order)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return list; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _sortCards: function(order, u, v) { | 
					
						
							|  |  |  |       var ud = this.getBoard().getOrderVector(u.getPHID(), order); | 
					
						
							|  |  |  |       var vd = this.getBoard().getOrderVector(v.getPHID(), order); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       for (var ii = 0; ii < ud.length; ii++) { | 
					
						
							|  |  |  |         if (ud[ii] > vd[ii]) { | 
					
						
							|  |  |  |           return 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (ud[ii] < vd[ii]) { | 
					
						
							|  |  |  |           return -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return 0; | 
					
						
							| 
									
										
										
										
											2016-02-10 13:53:36 -08:00
										 |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _redrawFrame: function() { | 
					
						
							|  |  |  |       var cards = this.getCards(); | 
					
						
							|  |  |  |       var board = this.getBoard(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var points = {}; | 
					
						
							| 
									
										
										
										
											2016-03-10 18:54:17 -08:00
										 |  |  |       var count = 0; | 
					
						
							| 
									
										
										
										
											2016-09-27 09:29:43 -07:00
										 |  |  |       var decimal_places = 0; | 
					
						
							| 
									
										
										
										
											2016-02-10 13:53:36 -08:00
										 |  |  |       for (var phid in cards) { | 
					
						
							|  |  |  |         var card = cards[phid]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         var card_points; | 
					
						
							|  |  |  |         if (board.getPointsEnabled()) { | 
					
						
							|  |  |  |           card_points = card.getPoints(); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           card_points = 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (card_points !== null) { | 
					
						
							|  |  |  |           var status = card.getStatus(); | 
					
						
							|  |  |  |           if (!points[status]) { | 
					
						
							|  |  |  |             points[status] = 0; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           points[status] += card_points; | 
					
						
							| 
									
										
										
										
											2016-09-27 09:29:43 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |           // Count the number of decimal places in the point value with the
 | 
					
						
							|  |  |  |           // most decimal digits. We'll use the same precision when rendering
 | 
					
						
							|  |  |  |           // the point sum. This avoids rounding errors and makes the display
 | 
					
						
							|  |  |  |           // a little more consistent.
 | 
					
						
							|  |  |  |           var parts = card_points.toString().split('.'); | 
					
						
							|  |  |  |           if (parts[1]) { | 
					
						
							|  |  |  |             decimal_places = Math.max(decimal_places, parts[1].length); | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2016-02-10 13:53:36 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-03-10 18:54:17 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         count++; | 
					
						
							| 
									
										
										
										
											2016-02-10 13:53:36 -08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var total_points = 0; | 
					
						
							|  |  |  |       for (var k in points) { | 
					
						
							|  |  |  |         total_points += points[k]; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2016-09-27 09:29:43 -07:00
										 |  |  |       total_points = total_points.toFixed(decimal_places); | 
					
						
							| 
									
										
										
										
											2016-02-10 13:53:36 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       var limit = this.getPointLimit(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var display_value; | 
					
						
							|  |  |  |       if (limit !== null && limit !== 0) { | 
					
						
							|  |  |  |         display_value = total_points + ' / ' + limit; | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         display_value = total_points; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-10 18:54:17 -08:00
										 |  |  |       if (board.getPointsEnabled()) { | 
					
						
							|  |  |  |         display_value = count + ' | ' + display_value; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-10 13:53:36 -08:00
										 |  |  |       var over_limit = ((limit !== null) && (total_points > limit)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var content_node = this.getPointsContentNode(); | 
					
						
							|  |  |  |       var points_node = this.getPointsNode(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       JX.DOM.setContent(content_node, display_value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var is_empty = !this.getCardPHIDs().length; | 
					
						
							|  |  |  |       var panel = JX.DOM.findAbove(this.getRoot(), 'div', 'workpanel'); | 
					
						
							|  |  |  |       JX.DOM.alterClass(panel, 'project-panel-empty', is_empty); | 
					
						
							|  |  |  |       JX.DOM.alterClass(panel, 'project-panel-over-limit', over_limit); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var color_map = { | 
					
						
							|  |  |  |         'phui-tag-shade-disabled': (total_points === 0), | 
					
						
							|  |  |  |         'phui-tag-shade-blue': (total_points > 0 && !over_limit), | 
					
						
							|  |  |  |         'phui-tag-shade-red': (over_limit) | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       for (var c in color_map) { | 
					
						
							|  |  |  |         JX.DOM.alterClass(points_node, c, !!color_map[c]); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       JX.DOM.show(points_node); | 
					
						
							| 
									
										
										
										
											2016-02-10 05:59:46 -08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }); |