@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
at upstream/main 213 lines 5.1 kB view raw
1<?php 2 3final class ManiphestTaskGraph 4 extends PhabricatorObjectGraph { 5 6 private $seedMaps = array(); 7 private $isStandalone; 8 9 protected function getEdgeTypes() { 10 return array( 11 ManiphestTaskDependedOnByTaskEdgeType::EDGECONST, 12 ManiphestTaskDependsOnTaskEdgeType::EDGECONST, 13 ); 14 } 15 16 protected function getParentEdgeType() { 17 return ManiphestTaskDependsOnTaskEdgeType::EDGECONST; 18 } 19 20 protected function newQuery() { 21 return new ManiphestTaskQuery(); 22 } 23 24 protected function isClosed($object) { 25 return $object->isClosed(); 26 } 27 28 public function setIsStandalone($is_standalone) { 29 $this->isStandalone = $is_standalone; 30 return $this; 31 } 32 33 public function getIsStandalone() { 34 return $this->isStandalone; 35 } 36 37 protected function newTableRow($phid, $object, $trace) { 38 $viewer = $this->getViewer(); 39 40 Javelin::initBehavior('phui-hovercards'); 41 42 if ($object) { 43 $status = $object->getStatus(); 44 $priority = $object->getPriority(); 45 $status_icon = ManiphestTaskStatus::getStatusIcon($status); 46 $status_name = ManiphestTaskStatus::getTaskStatusName($status); 47 48 $priority_color = ManiphestTaskPriority::getTaskPriorityColor($priority); 49 if ($object->isClosed()) { 50 $priority_color = 'grey'; 51 } 52 53 $status = array( 54 id(new PHUIIconView())->setIcon($status_icon, $priority_color), 55 ' ', 56 $status_name, 57 ); 58 59 $owner_phid = $object->getOwnerPHID(); 60 if ($owner_phid) { 61 $assigned = $viewer->renderHandle($owner_phid); 62 } else { 63 $assigned = phutil_tag('em', array(), pht('None')); 64 } 65 66 $link = javelin_tag( 67 'a', 68 array( 69 'href' => $object->getURI(), 70 'sigil' => 'hovercard', 71 'meta' => array( 72 'hovercardSpec' => array( 73 'objectPHID' => $object->getPHID(), 74 ), 75 ), 76 ), 77 $object->getTitle()); 78 79 $link = array( 80 phutil_tag( 81 'span', 82 array( 83 'class' => 'object-name', 84 ), 85 $object->getMonogram()), 86 ' ', 87 $link, 88 ); 89 90 $subtype_tag = null; 91 92 $subtype = $object->newSubtypeObject(); 93 if ($subtype && $subtype->hasTagView()) { 94 $subtype_tag = $subtype->newTagView() 95 ->setSlimShady(true); 96 } 97 } else { 98 $status = null; 99 $assigned = null; 100 $subtype_tag = null; 101 $link = $viewer->renderHandle($phid); 102 } 103 104 if ($this->isParentTask($phid)) { 105 $marker = 'fa-chevron-circle-up bluegrey'; 106 $marker_tip = pht('Direct Parent'); 107 } else if ($this->isChildTask($phid)) { 108 $marker = 'fa-chevron-circle-down bluegrey'; 109 $marker_tip = pht('Direct Subtask'); 110 } else { 111 $marker = null; 112 } 113 114 if ($marker) { 115 $marker = id(new PHUIIconView()) 116 ->setIcon($marker) 117 ->addSigil('has-tooltip') 118 ->setMetadata( 119 array( 120 'tip' => $marker_tip, 121 'align' => 'E', 122 )); 123 } 124 125 return array( 126 $marker, 127 $trace, 128 $status, 129 $subtype_tag, 130 $assigned, 131 $link, 132 ); 133 } 134 135 protected function newTable(AphrontTableView $table) { 136 $subtype_map = id(new ManiphestTask())->newEditEngineSubtypeMap(); 137 $has_subtypes = ($subtype_map->getCount() > 1); 138 139 return $table 140 ->setHeaders( 141 array( 142 null, 143 null, 144 pht('Status'), 145 pht('Subtype'), 146 pht('Assigned'), 147 pht('Task'), 148 )) 149 ->setColumnClasses( 150 array( 151 'nudgeright', 152 'threads', 153 'graph-status', 154 null, 155 null, 156 'wide pri object-link', 157 )) 158 ->setColumnVisibility( 159 array( 160 true, 161 !$this->getRenderOnlyAdjacentNodes(), 162 true, 163 $has_subtypes, 164 )) 165 ->setDeviceVisibility( 166 array( 167 true, 168 169 // On mobile, we only show the actual graph drawing if we're on the 170 // standalone page, since it can take over the screen otherwise. 171 $this->getIsStandalone(), 172 true, 173 174 // On mobile, don't show subtypes since they're relatively less 175 // important and we're more pressured for space. 176 false, 177 )); 178 } 179 180 private function isParentTask($task_phid) { 181 $map = $this->getSeedMap(ManiphestTaskDependedOnByTaskEdgeType::EDGECONST); 182 return isset($map[$task_phid]); 183 } 184 185 private function isChildTask($task_phid) { 186 $map = $this->getSeedMap(ManiphestTaskDependsOnTaskEdgeType::EDGECONST); 187 return isset($map[$task_phid]); 188 } 189 190 private function getSeedMap($type) { 191 if (!isset($this->seedMaps[$type])) { 192 $maps = $this->getEdges($type); 193 $phids = idx($maps, $this->getSeedPHID(), array()); 194 $phids = array_fuse($phids); 195 $this->seedMaps[$type] = $phids; 196 } 197 198 return $this->seedMaps[$type]; 199 } 200 201 protected function newEllipsisRow() { 202 return array( 203 null, 204 null, 205 null, 206 null, 207 null, 208 pht("\xC2\xB7 \xC2\xB7 \xC2\xB7"), 209 ); 210 } 211 212 213}