@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Show task counts in column headers on Workboards

Summary: Ref T4427. This always counts 1 task = 1 point. The tricky bit is making this update in JS.

Test Plan: {F190900}

Reviewers: btrahan, chad

Reviewed By: chad

Subscribers: epriestley

Maniphest Tasks: T4427

Differential Revision: https://secure.phabricator.com/D10275

+82 -17
+10 -10
resources/celerity/map.php
··· 415 415 'rsrc/js/application/policy/behavior-policy-rule-editor.js' => 'fe9a552f', 416 416 'rsrc/js/application/ponder/behavior-votebox.js' => '4e9b766b', 417 417 'rsrc/js/application/projects/behavior-boards-dropdown.js' => '0ec56e1d', 418 - 'rsrc/js/application/projects/behavior-project-boards.js' => 'd4bf1f3c', 418 + 'rsrc/js/application/projects/behavior-project-boards.js' => 'e4b6c65a', 419 419 'rsrc/js/application/projects/behavior-project-create.js' => '065227cc', 420 420 'rsrc/js/application/projects/behavior-reorder-columns.js' => 'e1d25dfb', 421 421 'rsrc/js/application/releeph/releeph-preview-branch.js' => 'b2b4fbaf', ··· 639 639 'javelin-behavior-policy-control' => 'f3fef818', 640 640 'javelin-behavior-policy-rule-editor' => 'fe9a552f', 641 641 'javelin-behavior-ponder-votebox' => '4e9b766b', 642 - 'javelin-behavior-project-boards' => 'd4bf1f3c', 642 + 'javelin-behavior-project-boards' => 'e4b6c65a', 643 643 'javelin-behavior-project-create' => '065227cc', 644 644 'javelin-behavior-refresh-csrf' => '7814b593', 645 645 'javelin-behavior-releeph-preview-branch' => 'b2b4fbaf', ··· 1693 1693 'javelin-dom', 1694 1694 'javelin-view', 1695 1695 ), 1696 - 'd4bf1f3c' => array( 1697 - 'javelin-behavior', 1698 - 'javelin-dom', 1699 - 'javelin-util', 1700 - 'javelin-stratcom', 1701 - 'javelin-workflow', 1702 - 'phabricator-draggable-list', 1703 - ), 1704 1696 'd4eecc63' => array( 1705 1697 'javelin-behavior', 1706 1698 'javelin-dom', ··· 1781 1773 'javelin-vector', 1782 1774 'javelin-dom', 1783 1775 'javelin-uri', 1776 + ), 1777 + 'e4b6c65a' => array( 1778 + 'javelin-behavior', 1779 + 'javelin-dom', 1780 + 'javelin-util', 1781 + 'javelin-stratcom', 1782 + 'javelin-workflow', 1783 + 'phabricator-draggable-list', 1784 1784 ), 1785 1785 'e566f52c' => array( 1786 1786 'javelin-behavior',
+19 -3
src/applications/project/controller/PhabricatorProjectBoardViewController.php
··· 220 220 $this->handles = ManiphestTaskListView::loadTaskHandles($viewer, $tasks); 221 221 222 222 foreach ($columns as $column) { 223 + $task_phids = idx($task_map, $column->getPHID(), array()); 224 + $column_tasks = array_select_keys($tasks, $task_phids); 225 + 223 226 $panel = id(new PHUIWorkpanelView()) 224 227 ->setHeader($column->getDisplayName()) 225 228 ->setHeaderColor($column->getHeaderColor()); ··· 227 230 $column_menu = $this->buildColumnMenu($project, $column); 228 231 $panel->addHeaderAction($column_menu); 229 232 233 + $tag_id = celerity_generate_unique_node_id(); 234 + $tag_content_id = celerity_generate_unique_node_id(); 235 + 236 + $count_tag = id(new PHUITagView()) 237 + ->setType(PHUITagView::TYPE_SHADE) 238 + ->setShade(PHUITagView::COLOR_BLUE) 239 + ->setID($tag_id) 240 + ->setName(phutil_tag('span', array('id' => $tag_content_id), '-')) 241 + ->setStyle('display: none'); 242 + 243 + $panel->setHeaderTag($count_tag); 244 + 230 245 $cards = id(new PHUIObjectItemListView()) 231 246 ->setUser($viewer) 232 247 ->setFlush(true) ··· 235 250 ->setMetadata( 236 251 array( 237 252 'columnPHID' => $column->getPHID(), 253 + 'countTagID' => $tag_id, 254 + 'countTagContentID' => $tag_content_id, 238 255 )); 239 256 240 - $task_phids = idx($task_map, $column->getPHID(), array()); 241 - foreach (array_select_keys($tasks, $task_phids) as $task) { 257 + foreach ($column_tasks as $task) { 242 258 $owner = null; 243 259 if ($task->getOwnerPHID()) { 244 260 $owner = $this->handles[$task->getOwnerPHID()]; ··· 253 269 } 254 270 $panel->setCards($cards); 255 271 256 - if (!$task_phids) { 272 + if (!$column_tasks) { 257 273 $cards->addClass('project-column-empty'); 258 274 } 259 275
+1
src/applications/project/view/ProjectBoardTaskCard.php
··· 35 35 $this->canEdit = $can_edit; 36 36 return $this; 37 37 } 38 + 38 39 public function getCanEdit() { 39 40 return $this->canEdit; 40 41 }
+10
src/view/phui/PHUIWorkpanelView.php
··· 7 7 private $footerAction; 8 8 private $headerColor = PHUIActionHeaderView::HEADER_GREY; 9 9 private $headerActions = array(); 10 + private $headerTag; 10 11 11 12 public function setCards(PHUIObjectItemListView $cards) { 12 13 $this->cards[] = $cards; ··· 33 34 return $this; 34 35 } 35 36 37 + public function setHeaderTag(PHUITagView $tag) { 38 + $this->headerTag = $tag; 39 + return $this; 40 + } 41 + 36 42 public function getTagAttributes() { 37 43 return array( 38 44 'class' => 'phui-workpanel-view', ··· 58 64 $header = id(new PHUIActionHeaderView()) 59 65 ->setHeaderTitle($this->header) 60 66 ->setHeaderColor($this->headerColor); 67 + 68 + if ($this->headerTag) { 69 + $header->setTag($this->headerTag); 70 + } 61 71 62 72 foreach ($this->headerActions as $action) { 63 73 $header->addAction($action);
+42 -4
webroot/rsrc/js/application/projects/behavior-project-boards.js
··· 14 14 return JX.DOM.scry(col, 'li', 'project-card'); 15 15 } 16 16 17 - function onupdate(node) { 18 - JX.DOM.alterClass(node, 'project-column-empty', !this.findItems().length); 17 + function onupdate(col) { 18 + var data = JX.Stratcom.getData(col); 19 + var cards = finditems(col); 20 + 21 + // Add the "empty" CSS class if the column has nothing in it. 22 + JX.DOM.alterClass(col, 'project-column-empty', !cards.length); 23 + 24 + // Update the count of tasks in the column header. 25 + if (!data.countTagNode) { 26 + data.countTagNode = JX.$(data.countTagID); 27 + JX.DOM.show(data.countTagNode); 28 + } 29 + 30 + var sum = 0; 31 + for (var ii = 0; ii < cards.length; ii++) { 32 + // TODO: Allow this to be computed in some more clever way. 33 + sum += 1; 34 + } 35 + 36 + JX.DOM.setContent(JX.$(data.countTagContentID), sum); 37 + 38 + // TODO: This is a little bit hacky, but we don't have a PHUIX version of 39 + // this element yet. 40 + 41 + var color_map = { 42 + 'phui-tag-shade-disabled': (sum === 0), 43 + 'phui-tag-shade-blue': (sum > 0) 44 + }; 45 + for (var k in color_map) { 46 + JX.DOM.alterClass(data.countTagNode, k, color_map[k]); 47 + } 19 48 } 20 49 21 50 function onresponse(response, item, list) { ··· 24 53 JX.DOM.replace(item, JX.$H(response.task)); 25 54 } 26 55 56 + function getcolumns() { 57 + return JX.DOM.scry(JX.$(config.boardID), 'ul', 'project-column'); 58 + } 59 + 27 60 function colsort(u, v) { 28 61 var ud = JX.Stratcom.getData(u).sort || []; 29 62 var vd = JX.Stratcom.getData(v).sort || []; ··· 93 126 94 127 var lists = []; 95 128 var ii; 96 - var cols = JX.DOM.scry(JX.$(config.boardID), 'ul', 'project-column'); 129 + var cols = getcolumns(); 97 130 98 131 for (ii = 0; ii < cols.length; ii++) { 99 132 var list = new JX.DraggableList('project-card', cols[ii]) ··· 105 138 list.listen('didDrop', JX.bind(null, ondrop, list)); 106 139 107 140 lists.push(list); 141 + 142 + onupdate(cols[ii]); 108 143 } 109 144 110 145 for (ii = 0; ii < lists.length; ii++) { ··· 141 176 items.sort(colsort); 142 177 143 178 JX.DOM.setContent(column, items); 179 + 180 + onupdate(column); 144 181 }; 145 182 146 183 JX.Stratcom.listen( ··· 175 212 projects: config.projectPHID, 176 213 order: config.order 177 214 }; 178 - var cols = JX.DOM.scry(JX.$(config.boardID), 'ul', 'project-column'); 215 + var cols = getcolumns(); 179 216 var ii; 180 217 var column; 181 218 for (ii = 0; ii < cols.length; ii++) { ··· 188 225 .setHandler(JX.bind(null, onedit, column)) 189 226 .start(); 190 227 }); 228 + 191 229 });