@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 recaptime-dev/main 347 lines 8.2 kB view raw
1<?php 2 3final class DifferentialRevisionUpdateHistoryView extends AphrontView { 4 5 private $diffs = array(); 6 private $selectedVersusDiffID; 7 private $selectedDiffID; 8 private $commitsForLinks = array(); 9 private $unitStatus = array(); 10 11 /** 12 * @param array<DifferentialDiff> $diffs 13 */ 14 public function setDiffs(array $diffs) { 15 assert_instances_of($diffs, DifferentialDiff::class); 16 $this->diffs = $diffs; 17 return $this; 18 } 19 20 public function setSelectedVersusDiffID($id) { 21 $this->selectedVersusDiffID = $id; 22 return $this; 23 } 24 25 public function setSelectedDiffID($id) { 26 $this->selectedDiffID = $id; 27 return $this; 28 } 29 30 /** 31 * @param array<PhabricatorRepositoryCommit> $commits 32 */ 33 public function setCommitsForLinks(array $commits) { 34 assert_instances_of($commits, PhabricatorRepositoryCommit::class); 35 $this->commitsForLinks = $commits; 36 return $this; 37 } 38 39 public function setDiffUnitStatuses(array $unit_status) { 40 $this->unitStatus = $unit_status; 41 return $this; 42 } 43 44 public function render() { 45 $this->requireResource('differential-core-view-css'); 46 $this->requireResource('differential-revision-history-css'); 47 48 $data = array( 49 array( 50 'name' => pht('Base'), 51 'id' => null, 52 'desc' => pht('Base'), 53 'age' => null, 54 'obj' => null, 55 ), 56 ); 57 58 $seq = 0; 59 foreach ($this->diffs as $diff) { 60 $data[] = array( 61 'name' => pht('Diff %d', ++$seq), 62 'id' => $diff->getID(), 63 'desc' => $diff->getDescription(), 64 'age' => $diff->getDateCreated(), 65 'obj' => $diff, 66 ); 67 } 68 69 $max_id = $diff->getID(); 70 $revision_id = $diff->getRevisionID(); 71 72 $idx = 0; 73 $rows = array(); 74 $disable = false; 75 $radios = array(); 76 $last_base = null; 77 $rowc = array(); 78 foreach ($data as $row) { 79 80 $diff = $row['obj']; 81 $name = $row['name']; 82 $id = $row['id']; 83 84 $old_class = false; 85 $new_class = false; 86 87 if ($id) { 88 $new_checked = ($this->selectedDiffID == $id); 89 $new = javelin_tag( 90 'input', 91 array( 92 'type' => 'radio', 93 'name' => 'id', 94 'value' => $id, 95 'checked' => $new_checked ? 'checked' : null, 96 'sigil' => 'differential-new-radio', 97 )); 98 if ($new_checked) { 99 $new_class = true; 100 $disable = true; 101 } 102 $new = phutil_tag( 103 'div', 104 array( 105 'class' => 'differential-update-history-radio', 106 ), 107 $new); 108 } else { 109 $new = null; 110 } 111 112 if ($max_id != $id) { 113 $uniq = celerity_generate_unique_node_id(); 114 $old_checked = ($this->selectedVersusDiffID == $id); 115 $old = phutil_tag( 116 'input', 117 array( 118 'type' => 'radio', 119 'name' => 'vs', 120 'value' => $id, 121 'id' => $uniq, 122 'checked' => $old_checked ? 'checked' : null, 123 'disabled' => $disable ? 'disabled' : null, 124 )); 125 $radios[] = $uniq; 126 if ($old_checked) { 127 $old_class = true; 128 } 129 $old = phutil_tag( 130 'div', 131 array( 132 'class' => 'differential-update-history-radio', 133 ), 134 $old); 135 } else { 136 $old = null; 137 } 138 139 $desc = $row['desc']; 140 141 if ($row['age']) { 142 $age = phabricator_datetime($row['age'], $this->getUser()); 143 } else { 144 $age = null; 145 } 146 147 if ($diff) { 148 $lint = $this->newLintStatusView($diff); 149 $unit = $this->newUnitStatusView($diff); 150 $base = $this->renderBaseRevision($diff); 151 } else { 152 $lint = null; 153 $unit = null; 154 $base = null; 155 } 156 157 if ($last_base !== null && $base !== $last_base) { 158 // TODO: Render some kind of notice about rebases. 159 } 160 $last_base = $base; 161 162 if ($revision_id) { 163 $id_link = phutil_tag( 164 'a', 165 array( 166 'href' => '/D'.$revision_id.'?id='.$id, 167 ), 168 $id); 169 } else { 170 $id_link = phutil_tag( 171 'a', 172 array( 173 'href' => '/differential/diff/'.$id.'/', 174 ), 175 $id); 176 } 177 178 $rows[] = array( 179 $name, 180 $id_link, 181 $base, 182 $desc, 183 $age, 184 $lint, 185 $unit, 186 $old, 187 $new, 188 ); 189 190 $classes = array(); 191 if ($old_class) { 192 $classes[] = 'differential-update-history-old-now'; 193 } 194 if ($new_class) { 195 $classes[] = 'differential-update-history-new-now'; 196 } 197 $rowc[] = nonempty(implode(' ', $classes), null); 198 } 199 200 Javelin::initBehavior( 201 'differential-diff-radios', 202 array( 203 'radios' => $radios, 204 )); 205 206 $table = new AphrontTableView($rows); 207 $table->setHeaders( 208 array( 209 pht('Diff'), 210 pht('ID'), 211 pht('Base'), 212 pht('Description'), 213 pht('Created'), 214 pht('Lint'), 215 pht('Unit'), 216 '', 217 '', 218 )); 219 $table->setColumnClasses( 220 array( 221 'pri', 222 '', 223 '', 224 'wide', 225 'date', 226 'center', 227 'center', 228 'center differential-update-history-old', 229 'center differential-update-history-new', 230 )); 231 $table->setRowClasses($rowc); 232 $table->setDeviceVisibility( 233 array( 234 true, 235 true, 236 false, 237 true, 238 false, 239 false, 240 false, 241 true, 242 true, 243 )); 244 245 $show_diff = phutil_tag( 246 'div', 247 array( 248 'class' => 'differential-update-history-footer', 249 ), 250 array( 251 phutil_tag( 252 'button', 253 array(), 254 pht('Show Diff')), 255 )); 256 257 $content = phabricator_form( 258 $this->getUser(), 259 array( 260 'action' => '/D'.$revision_id.'#toc', 261 ), 262 array( 263 $table, 264 $show_diff, 265 )); 266 267 return $content; 268 } 269 270 private function renderBaseRevision(DifferentialDiff $diff) { 271 switch ($diff->getSourceControlSystem()) { 272 case 'git': 273 $base = $diff->getSourceControlBaseRevision(); 274 if (strpos($base, '@') === false) { 275 $label = substr($base, 0, 7); 276 } else { 277 // The diff is from git-svn 278 $base = explode('@', $base); 279 $base = last($base); 280 $label = $base; 281 } 282 break; 283 case 'svn': 284 $base = $diff->getSourceControlBaseRevision(); 285 $base = explode('@', $base); 286 $base = last($base); 287 $label = $base; 288 break; 289 default: 290 $label = null; 291 break; 292 } 293 $link = null; 294 if ($label) { 295 $commit_for_link = idx( 296 $this->commitsForLinks, 297 $diff->getSourceControlBaseRevision()); 298 if ($commit_for_link) { 299 $link = phutil_tag( 300 'a', 301 array('href' => $commit_for_link->getURI()), 302 $label); 303 } else { 304 $link = $label; 305 } 306 } 307 return $link; 308 } 309 310 private function newLintStatusView(DifferentialDiff $diff) { 311 $value = $diff->getLintStatus(); 312 $status = DifferentialLintStatus::newStatusFromValue($value); 313 314 $icon = $status->getIconIcon(); 315 $color = $status->getIconColor(); 316 $name = $status->getName(); 317 318 return $this->newDiffStatusIconView($icon, $color, $name); 319 } 320 321 private function newUnitStatusView(DifferentialDiff $diff) { 322 $value = $diff->getUnitStatus(); 323 324 // NOTE: We may be overriding the value on the diff with a value from 325 // Harbormaster. 326 $value = idx($this->unitStatus, $diff->getPHID(), $value); 327 328 $status = DifferentialUnitStatus::newStatusFromValue($value); 329 330 $icon = $status->getIconIcon(); 331 $color = $status->getIconColor(); 332 $name = $status->getName(); 333 334 return $this->newDiffStatusIconView($icon, $color, $name); 335 } 336 337 private function newDiffStatusIconView($icon, $color, $name) { 338 return id(new PHUIIconView()) 339 ->setIcon($icon, $color) 340 ->addSigil('has-tooltip') 341 ->setMetadata( 342 array( 343 'tip' => $name, 344 )); 345 } 346 347}