[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 /** 2 * @provides javelin-behavior-project-boards 3 * @requires javelin-behavior 4 * javelin-dom 5 * javelin-util 6 * javelin-vector 7 * javelin-stratcom 8 * javelin-workflow 9 * phabricator-draggable-list 10 */ 11 12 JX.behavior('project-boards', function(config) { 13 14 function finditems(col) { 15 return JX.DOM.scry(col, 'li', 'project-card'); 16 } 17 18 function onupdate(col) { 19 var data = JX.Stratcom.getData(col); 20 var cards = finditems(col); 21 22 // Update the count of tasks in the column header. 23 if (!data.countTagNode) { 24 data.countTagNode = JX.$(data.countTagID); 25 JX.DOM.show(data.countTagNode); 26 } 27 28 var sum = 0; 29 for (var ii = 0; ii < cards.length; ii++) { 30 // TODO: Allow this to be computed in some more clever way. 31 sum += 1; 32 } 33 34 // TODO: This is a little bit hacky, but we don't have a PHUIX version of 35 // this element yet. 36 37 var over_limit = (data.pointLimit && (sum > data.pointLimit)); 38 39 var display_value = sum; 40 if (data.pointLimit) { 41 display_value = sum + ' / ' + data.pointLimit; 42 } 43 JX.DOM.setContent(JX.$(data.countTagContentID), display_value); 44 45 46 var panel_map = { 47 'project-panel-empty': !cards.length, 48 'project-panel-over-limit': over_limit 49 }; 50 var panel = JX.DOM.findAbove(col, 'div', 'workpanel'); 51 for (var k in panel_map) { 52 JX.DOM.alterClass(panel, k, !!panel_map[k]); 53 } 54 55 var color_map = { 56 'phui-tag-shade-disabled': (sum === 0), 57 'phui-tag-shade-blue': (sum > 0 && !over_limit), 58 'phui-tag-shade-red': (over_limit) 59 }; 60 for (var k in color_map) { 61 JX.DOM.alterClass(data.countTagNode, k, !!color_map[k]); 62 } 63 } 64 65 function onresponse(response, item, list) { 66 list.unlock(); 67 JX.DOM.alterClass(item, 'drag-sending', false); 68 JX.DOM.replace(item, JX.$H(response.task)); 69 } 70 71 function getcolumns() { 72 return JX.DOM.scry(JX.$(config.boardID), 'ul', 'project-column'); 73 } 74 75 function colsort(u, v) { 76 var ud = JX.Stratcom.getData(u).sort || []; 77 var vd = JX.Stratcom.getData(v).sort || []; 78 79 for (var ii = 0; ii < ud.length; ii++) { 80 81 if (parseInt(ud[ii]) < parseInt(vd[ii])) { 82 return 1; 83 } 84 if (parseInt(ud[ii]) > parseInt(vd[ii])) { 85 return -1; 86 } 87 } 88 89 return 0; 90 } 91 92 function getcontainer() { 93 return JX.DOM.find( 94 JX.$(config.boardID), 95 'div', 96 'aphront-multi-column-view'); 97 } 98 99 function onbegindrag(item) { 100 // If the longest column on the board is taller than the window, the board 101 // will scroll vertically. Dragging an item to the longest column may 102 // make it longer, by the total height of the board, plus the height of 103 // the drop target. 104 105 // If this happens, the scrollbar will jump around and the scroll position 106 // can be adjusted in a disorienting way. To reproduce this, drag a task 107 // to the bottom of the longest column on a scrolling board and wave the 108 // task in and out of the column. The scroll bar will jump around and 109 // it will be hard to lock onto a target. 110 111 // To fix this, set the minimum board height to the current board height 112 // plus the size of the drop target (which is the size of the item plus 113 // a bit of margin). This makes sure the scroll bar never needs to 114 // recalculate. 115 116 var item_size = JX.Vector.getDim(item); 117 var container = getcontainer(); 118 var container_size = JX.Vector.getDim(container); 119 120 container.style.minHeight = (item_size.y + container_size.y + 12) + 'px'; 121 } 122 123 function onenddrag() { 124 getcontainer().style.minHeight = ''; 125 } 126 127 function ondrop(list, item, after) { 128 list.lock(); 129 JX.DOM.alterClass(item, 'drag-sending', true); 130 131 var item_phid = JX.Stratcom.getData(item).objectPHID; 132 var data = { 133 objectPHID: item_phid, 134 columnPHID: JX.Stratcom.getData(list.getRootNode()).columnPHID 135 }; 136 137 var after_phid = null; 138 var items = finditems(list.getRootNode()); 139 if (after) { 140 after_phid = JX.Stratcom.getData(after).objectPHID; 141 data.afterPHID = after_phid; 142 } 143 var ii; 144 var ii_item; 145 var ii_item_phid; 146 var ii_prev_item_phid = null; 147 var before_phid = null; 148 for (ii = 0; ii < items.length; ii++) { 149 ii_item = items[ii]; 150 ii_item_phid = JX.Stratcom.getData(ii_item).objectPHID; 151 if (ii_item_phid == item_phid) { 152 // skip the item we just dropped 153 continue; 154 } 155 // note this handles when there is no after phid - we are at the top of 156 // the list - quite nicely 157 if (ii_prev_item_phid == after_phid) { 158 before_phid = ii_item_phid; 159 break; 160 } 161 ii_prev_item_phid = ii_item_phid; 162 } 163 if (before_phid) { 164 data.beforePHID = before_phid; 165 } 166 167 data.order = config.order; 168 169 var workflow = new JX.Workflow(config.moveURI, data) 170 .setHandler(function(response) { 171 onresponse(response, item, list); 172 }); 173 174 workflow.start(); 175 } 176 177 var lists = []; 178 var ii; 179 var cols = getcolumns(); 180 181 for (ii = 0; ii < cols.length; ii++) { 182 var list = new JX.DraggableList('project-card', cols[ii]) 183 .setFindItemsHandler(JX.bind(null, finditems, cols[ii])); 184 185 list.listen('didSend', JX.bind(list, onupdate, cols[ii])); 186 list.listen('didReceive', JX.bind(list, onupdate, cols[ii])); 187 188 list.listen('didDrop', JX.bind(null, ondrop, list)); 189 190 list.listen('didBeginDrag', JX.bind(null, onbegindrag)); 191 list.listen('didEndDrag', JX.bind(null, onenddrag)); 192 193 lists.push(list); 194 195 onupdate(cols[ii]); 196 } 197 198 for (ii = 0; ii < lists.length; ii++) { 199 lists[ii].setGroup(lists); 200 } 201 202 var onedit = function(column, r) { 203 var new_card = JX.$H(r.tasks).getNode(); 204 var new_data = JX.Stratcom.getData(new_card); 205 var items = finditems(column); 206 var edited = false; 207 208 for (var ii = 0; ii < items.length; ii++) { 209 var item = items[ii]; 210 211 var data = JX.Stratcom.getData(item); 212 var phid = data.objectPHID; 213 214 if (phid == new_data.objectPHID) { 215 items[ii] = new_card; 216 data = new_data; 217 edited = true; 218 } 219 220 data.sort = r.data.sortMap[data.objectPHID] || data.sort; 221 } 222 223 // this is an add then...! 224 if (!edited) { 225 items[items.length + 1] = new_card; 226 new_data.sort = r.data.sortMap[new_data.objectPHID] || new_data.sort; 227 } 228 229 items.sort(colsort); 230 231 JX.DOM.setContent(column, items); 232 233 onupdate(column); 234 }; 235 236 JX.Stratcom.listen( 237 'click', 238 ['edit-project-card'], 239 function(e) { 240 e.kill(); 241 var column = e.getNode('project-column'); 242 var request_data = { 243 responseType: 'card', 244 columnPHID: JX.Stratcom.getData(column).columnPHID, 245 order: config.order 246 }; 247 new JX.Workflow(e.getNode('tag:a').href, request_data) 248 .setHandler(JX.bind(null, onedit, column)) 249 .start(); 250 }); 251 252 JX.Stratcom.listen( 253 'click', 254 ['column-add-task'], 255 function (e) { 256 257 // We want the 'boards-dropdown-menu' behavior to see this event and 258 // close the dropdown, but don't want to follow the link. 259 e.prevent(); 260 261 var column_phid = e.getNodeData('column-add-task').columnPHID; 262 var request_data = { 263 responseType: 'card', 264 columnPHID: column_phid, 265 projects: config.projectPHID, 266 order: config.order 267 }; 268 var cols = getcolumns(); 269 var ii; 270 var column; 271 for (ii = 0; ii < cols.length; ii++) { 272 if (JX.Stratcom.getData(cols[ii]).columnPHID == column_phid) { 273 column = cols[ii]; 274 break; 275 } 276 } 277 new JX.Workflow(config.createURI, request_data) 278 .setHandler(JX.bind(null, onedit, column)) 279 .start(); 280 }); 281 282 });
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |