@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.

Render parent and child tasks in Maniphest with a graph trace

Summary: Ref T4788. This seems reasonable locally, but not sure how it will feel on real data. Might need some tweaks, or might just be a terrible idea.

Test Plan: {F1708059}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T4788

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

+135 -15
+2
src/__phutil_library_map__.php
··· 1430 1430 'ManiphestTaskEditBulkJobType' => 'applications/maniphest/bulk/ManiphestTaskEditBulkJobType.php', 1431 1431 'ManiphestTaskEditController' => 'applications/maniphest/controller/ManiphestTaskEditController.php', 1432 1432 'ManiphestTaskFulltextEngine' => 'applications/maniphest/search/ManiphestTaskFulltextEngine.php', 1433 + 'ManiphestTaskGraph' => 'infrastructure/graph/ManiphestTaskGraph.php', 1433 1434 'ManiphestTaskHasCommitEdgeType' => 'applications/maniphest/edge/ManiphestTaskHasCommitEdgeType.php', 1434 1435 'ManiphestTaskHasCommitRelationship' => 'applications/maniphest/relationship/ManiphestTaskHasCommitRelationship.php', 1435 1436 'ManiphestTaskHasDuplicateTaskEdgeType' => 'applications/maniphest/edge/ManiphestTaskHasDuplicateTaskEdgeType.php', ··· 5947 5948 'ManiphestTaskEditBulkJobType' => 'PhabricatorWorkerBulkJobType', 5948 5949 'ManiphestTaskEditController' => 'ManiphestController', 5949 5950 'ManiphestTaskFulltextEngine' => 'PhabricatorFulltextEngine', 5951 + 'ManiphestTaskGraph' => 'PhabricatorObjectGraph', 5950 5952 'ManiphestTaskHasCommitEdgeType' => 'PhabricatorEdgeType', 5951 5953 'ManiphestTaskHasCommitRelationship' => 'ManiphestTaskRelationship', 5952 5954 'ManiphestTaskHasDuplicateTaskEdgeType' => 'PhabricatorEdgeType',
+11 -11
src/applications/maniphest/controller/ManiphestTaskDetailController.php
··· 31 31 ->setTargetObject($task); 32 32 33 33 $e_commit = ManiphestTaskHasCommitEdgeType::EDGECONST; 34 - $e_dep_on = ManiphestTaskDependsOnTaskEdgeType::EDGECONST; 35 - $e_dep_by = ManiphestTaskDependedOnByTaskEdgeType::EDGECONST; 36 34 $e_rev = ManiphestTaskHasRevisionEdgeType::EDGECONST; 37 35 $e_mock = ManiphestTaskHasMockEdgeType::EDGECONST; 38 36 ··· 43 41 ->withEdgeTypes( 44 42 array( 45 43 $e_commit, 46 - $e_dep_on, 47 - $e_dep_by, 48 44 $e_rev, 49 45 $e_mock, 50 46 )); ··· 91 87 ->addPropertySection(pht('Description'), $description) 92 88 ->addPropertySection(pht('Details'), $details); 93 89 90 + $task_graph = id(new ManiphestTaskGraph()) 91 + ->setViewer($viewer) 92 + ->setSeedPHID($task->getPHID()) 93 + ->loadGraph(); 94 + if (!$task_graph->isEmpty()) { 95 + $graph_table = $task_graph->newGraphTable(); 96 + $view->addPropertySection(pht('Task Graph'), $graph_table); 97 + } 98 + 94 99 return $this->newPage() 95 100 ->setTitle($title) 96 101 ->setCrumbs($crumbs) ··· 186 191 $edit_uri = $this->getApplicationURI($edit_uri); 187 192 } 188 193 189 - $task_submenu = array(); 190 - 191 - $task_submenu[] = id(new PhabricatorActionView()) 194 + $subtask_item = id(new PhabricatorActionView()) 192 195 ->setName(pht('Create Subtask')) 193 196 ->setHref($edit_uri) 194 197 ->setIcon('fa-level-down') ··· 200 203 $task); 201 204 202 205 $submenu_actions = array( 206 + $subtask_item, 203 207 ManiphestTaskHasParentRelationship::RELATIONSHIPKEY, 204 208 ManiphestTaskHasSubtaskRelationship::RELATIONSHIPKEY, 205 209 ManiphestTaskMergeInRelationship::RELATIONSHIPKEY, ··· 280 284 } 281 285 282 286 $edge_types = array( 283 - ManiphestTaskDependedOnByTaskEdgeType::EDGECONST 284 - => pht('Parent Tasks'), 285 - ManiphestTaskDependsOnTaskEdgeType::EDGECONST 286 - => pht('Subtasks'), 287 287 ManiphestTaskHasRevisionEdgeType::EDGECONST 288 288 => pht('Differential Revisions'), 289 289 ManiphestTaskHasMockEdgeType::EDGECONST
+4
src/applications/maniphest/storage/ManiphestTask.php
··· 179 179 return 'T'.$this->getID(); 180 180 } 181 181 182 + public function getURI() { 183 + return '/'.$this->getMonogram(); 184 + } 185 + 182 186 public function attachGroupByProjectPHID($phid) { 183 187 $this->groupByProjectPHID = $phid; 184 188 return $this;
+6
src/applications/search/relationship/PhabricatorObjectRelationshipList.php
··· 52 52 $actions = array(); 53 53 54 54 foreach ($keys as $key) { 55 + // If we're passed a menu item, just include it verbatim. 56 + if ($key instanceof PhabricatorActionView) { 57 + $actions[] = $key; 58 + continue; 59 + } 60 + 55 61 $relationship = $this->getRelationship($key); 56 62 if (!$relationship) { 57 63 throw new Exception(
+23 -4
src/infrastructure/diff/view/PHUIDiffGraphView.php
··· 137 137 ); 138 138 } 139 139 140 - // If this is the last page in history, replace the "o" with an "x" so we 141 - // do not draw a connecting line downward, and replace "^" with an "X" for 142 - // repositories with exactly one commit. 140 + // If this is the last page in history, replace any "o" characters at the 141 + // bottom of columns with "x" characters so we do not draw a connecting 142 + // line downward, and replace "^" with an "X" for repositories with 143 + // exactly one commit. 143 144 if ($this->getIsTail() && $graph) { 145 + $terminated = array(); 146 + foreach (array_reverse(array_keys($graph)) as $key) { 147 + $line = $graph[$key]['line']; 148 + $len = strlen($line); 149 + for ($ii = 0; $ii < $len; $ii++) { 150 + if (isset($terminated[$ii])) { 151 + continue; 152 + } 153 + 154 + $c = $line[$ii]; 155 + if ($c == 'o') { 156 + $terminated[$ii] = true; 157 + $graph[$key]['line'][$ii] = 'x'; 158 + } else if ($c != ' ') { 159 + $terminated[$ii] = true; 160 + } 161 + } 162 + } 163 + 144 164 $last = array_pop($graph); 145 - $last['line'] = str_replace('o', 'x', $last['line']); 146 165 $last['line'] = str_replace('^', 'X', $last['line']); 147 166 $graph[] = $last; 148 167 }
+87
src/infrastructure/graph/ManiphestTaskGraph.php
··· 1 + <?php 2 + 3 + final class ManiphestTaskGraph 4 + extends PhabricatorObjectGraph { 5 + 6 + protected function getEdgeTypes() { 7 + return array( 8 + ManiphestTaskDependedOnByTaskEdgeType::EDGECONST, 9 + ManiphestTaskDependsOnTaskEdgeType::EDGECONST, 10 + ); 11 + } 12 + 13 + protected function getParentEdgeType() { 14 + return ManiphestTaskDependsOnTaskEdgeType::EDGECONST; 15 + } 16 + 17 + protected function newQuery() { 18 + return new ManiphestTaskQuery(); 19 + } 20 + 21 + protected function newTableRow($phid, $object, $trace) { 22 + $viewer = $this->getViewer(); 23 + 24 + if ($object) { 25 + $status = $object->getStatus(); 26 + $priority = $object->getPriority(); 27 + $status_icon = ManiphestTaskStatus::getStatusIcon($status); 28 + $status_name = ManiphestTaskStatus::getTaskStatusName($status); 29 + $priority_color = ManiphestTaskPriority::getTaskPriorityColor($priority); 30 + 31 + 32 + $status = array( 33 + id(new PHUIIconView())->setIcon($status_icon, $priority_color), 34 + ' ', 35 + $status_name, 36 + ); 37 + 38 + $owner_phid = $object->getOwnerPHID(); 39 + if ($owner_phid) { 40 + $assigned = $viewer->renderHandle($owner_phid); 41 + } else { 42 + $assigned = phutil_tag('em', array(), pht('None')); 43 + } 44 + 45 + $link = phutil_tag( 46 + 'a', 47 + array( 48 + 'href' => $object->getURI(), 49 + ), 50 + array( 51 + $object->getMonogram(), 52 + ' ', 53 + $object->getTitle(), 54 + )); 55 + } else { 56 + $status = null; 57 + $assigned = null; 58 + $link = $viewer->renderHandle($phid); 59 + } 60 + 61 + return array( 62 + $trace, 63 + $status, 64 + $assigned, 65 + $link, 66 + ); 67 + } 68 + 69 + protected function newTable(AphrontTableView $table) { 70 + return $table 71 + ->setHeaders( 72 + array( 73 + null, 74 + pht('Status'), 75 + pht('Assigned'), 76 + pht('Task'), 77 + )) 78 + ->setColumnClasses( 79 + array( 80 + 'threads', 81 + null, 82 + null, 83 + 'wide', 84 + )); 85 + } 86 + 87 + }
+2
src/infrastructure/graph/PhabricatorObjectGraph.php
··· 55 55 56 56 $map = array(); 57 57 foreach ($nodes as $node) { 58 + $map[$node] = array(); 59 + 58 60 foreach ($edge_types as $edge_type) { 59 61 $dst_phids = $query->getDestinationPHIDs( 60 62 array($node),