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

Convert commits to use unified table of contents

Summary:
Fixes T2183. We now use the same rendering element in both places.

Intentional changes:

- Package highlighting is out, coming back to both apps in next diff.
- removed redundant-feeling "Change" link. The information is now shown with a character ("M", "V", etc.) and the page is a click away under "History". Clicking the path also jumps you to substantially similar content. (We could restore it fairly easily, I just think it's probably the least useful thing in the table right now.)

Test Plan: Viewed a bunch of commits in Diffusion.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T2183

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

+162 -477
-4
src/__phutil_library_map__.php
··· 367 367 'DifferentialDiffQuery' => 'applications/differential/query/DifferentialDiffQuery.php', 368 368 'DifferentialDiffRepositoryHeraldField' => 'applications/differential/herald/DifferentialDiffRepositoryHeraldField.php', 369 369 'DifferentialDiffRepositoryProjectsHeraldField' => 'applications/differential/herald/DifferentialDiffRepositoryProjectsHeraldField.php', 370 - 'DifferentialDiffTableOfContentsView' => 'applications/differential/view/DifferentialDiffTableOfContentsView.php', 371 370 'DifferentialDiffTestCase' => 'applications/differential/storage/__tests__/DifferentialDiffTestCase.php', 372 371 'DifferentialDiffTransaction' => 'applications/differential/storage/DifferentialDiffTransaction.php', 373 372 'DifferentialDiffTransactionQuery' => 'applications/differential/query/DifferentialDiffTransactionQuery.php', ··· 519 518 'DiffusionCommitAutocloseHeraldField' => 'applications/diffusion/herald/DiffusionCommitAutocloseHeraldField.php', 520 519 'DiffusionCommitBranchesController' => 'applications/diffusion/controller/DiffusionCommitBranchesController.php', 521 520 'DiffusionCommitBranchesHeraldField' => 'applications/diffusion/herald/DiffusionCommitBranchesHeraldField.php', 522 - 'DiffusionCommitChangeTableView' => 'applications/diffusion/view/DiffusionCommitChangeTableView.php', 523 521 'DiffusionCommitCommitterHeraldField' => 'applications/diffusion/herald/DiffusionCommitCommitterHeraldField.php', 524 522 'DiffusionCommitController' => 'applications/diffusion/controller/DiffusionCommitController.php', 525 523 'DiffusionCommitDiffContentAddedHeraldField' => 'applications/diffusion/herald/DiffusionCommitDiffContentAddedHeraldField.php', ··· 4006 4004 'DifferentialDiffQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 4007 4005 'DifferentialDiffRepositoryHeraldField' => 'DifferentialDiffHeraldField', 4008 4006 'DifferentialDiffRepositoryProjectsHeraldField' => 'DifferentialDiffHeraldField', 4009 - 'DifferentialDiffTableOfContentsView' => 'AphrontView', 4010 4007 'DifferentialDiffTestCase' => 'PhutilTestCase', 4011 4008 'DifferentialDiffTransaction' => 'PhabricatorApplicationTransaction', 4012 4009 'DifferentialDiffTransactionQuery' => 'PhabricatorApplicationTransactionQuery', ··· 4178 4175 'DiffusionCommitAutocloseHeraldField' => 'DiffusionCommitHeraldField', 4179 4176 'DiffusionCommitBranchesController' => 'DiffusionController', 4180 4177 'DiffusionCommitBranchesHeraldField' => 'DiffusionCommitHeraldField', 4181 - 'DiffusionCommitChangeTableView' => 'DiffusionView', 4182 4178 'DiffusionCommitCommitterHeraldField' => 'DiffusionCommitHeraldField', 4183 4179 'DiffusionCommitController' => 'DiffusionController', 4184 4180 'DiffusionCommitDiffContentAddedHeraldField' => 'DiffusionCommitHeraldField',
+29
src/applications/differential/controller/DifferentialController.php
··· 21 21 return $this->buildSideNavView(true)->getMenu(); 22 22 } 23 23 24 + protected function buildTableOfContents( 25 + array $changesets, 26 + array $visible_changesets, 27 + array $coverage) { 28 + $viewer = $this->getViewer(); 29 + 30 + $toc_view = id(new PHUIDiffTableOfContentsListView()) 31 + ->setUser($viewer); 32 + 33 + foreach ($changesets as $changeset_id => $changeset) { 34 + $is_visible = isset($visible_changesets[$changeset_id]); 35 + $anchor = $changeset->getAnchorName(); 36 + 37 + $filename = $changeset->getFilename(); 38 + $coverage_id = 'differential-mcoverage-'.md5($filename); 39 + 40 + $item = id(new PHUIDiffTableOfContentsItemView()) 41 + ->setChangeset($changeset) 42 + ->setIsVisible($is_visible) 43 + ->setAnchor($anchor) 44 + ->setCoverage(idx($coverage, $filename)) 45 + ->setCoverageID($coverage_id); 46 + 47 + $toc_view->addItem($item); 48 + } 49 + 50 + return $toc_view; 51 + } 52 + 24 53 }
+4 -4
src/applications/differential/controller/DifferentialDiffViewController.php
··· 116 116 $changesets = $diff->loadChangesets(); 117 117 $changesets = msort($changesets, 'getSortKey'); 118 118 119 - $table_of_contents = id(new DifferentialDiffTableOfContentsView()) 120 - ->setChangesets($changesets) 121 - ->setVisibleChangesets($changesets) 122 - ->setCoverageMap($diff->loadCoverageMap($viewer)); 119 + $table_of_contents = $this->buildTableOfContents( 120 + $changesets, 121 + $changesets, 122 + $diff->loadCoverageMap($viewer)); 123 123 124 124 $refs = array(); 125 125 foreach ($changesets as $changeset) {
-30
src/applications/differential/controller/DifferentialRevisionViewController.php
··· 1036 1036 return $view; 1037 1037 } 1038 1038 1039 - private function buildTableOfContents( 1040 - array $changesets, 1041 - array $visible_changesets, 1042 - array $coverage) { 1043 - $viewer = $this->getViewer(); 1044 - 1045 - $toc_view = id(new PHUIDiffTableOfContentsListView()) 1046 - ->setUser($viewer); 1047 - 1048 - foreach ($changesets as $changeset_id => $changeset) { 1049 - $is_visible = isset($visible_changesets[$changeset_id]); 1050 - $anchor = $changeset->getAnchorName(); 1051 - 1052 - $filename = $changeset->getFilename(); 1053 - $coverage_id = 'differential-mcoverage-'.md5($filename); 1054 - 1055 - $item = id(new PHUIDiffTableOfContentsItemView()) 1056 - ->setChangeset($changeset) 1057 - ->setIsVisible($is_visible) 1058 - ->setAnchor($anchor) 1059 - ->setCoverage(idx($coverage, $filename)) 1060 - ->setCoverageID($coverage_id); 1061 - 1062 - $toc_view->addItem($item); 1063 - } 1064 - 1065 - return $toc_view; 1066 - } 1067 - 1068 - 1069 1039 }
-300
src/applications/differential/view/DifferentialDiffTableOfContentsView.php
··· 1 - <?php 2 - 3 - final class DifferentialDiffTableOfContentsView extends AphrontView { 4 - 5 - private $changesets = array(); 6 - private $visibleChangesets = array(); 7 - private $references = array(); 8 - private $repository; 9 - private $diff; 10 - private $renderURI = '/differential/changeset/'; 11 - private $coverageMap; 12 - 13 - public function setChangesets($changesets) { 14 - $this->changesets = $changesets; 15 - return $this; 16 - } 17 - 18 - public function setVisibleChangesets($visible_changesets) { 19 - $this->visibleChangesets = $visible_changesets; 20 - return $this; 21 - } 22 - 23 - public function setRenderingReferences(array $references) { 24 - $this->references = $references; 25 - return $this; 26 - } 27 - 28 - public function setRepository(PhabricatorRepository $repository) { 29 - $this->repository = $repository; 30 - return $this; 31 - } 32 - 33 - public function setDiff(DifferentialDiff $diff) { 34 - $this->diff = $diff; 35 - return $this; 36 - } 37 - 38 - public function setCoverageMap(array $coverage_map) { 39 - $this->coverageMap = $coverage_map; 40 - return $this; 41 - } 42 - 43 - public function render() { 44 - 45 - $this->requireResource('differential-core-view-css'); 46 - $this->requireResource('differential-table-of-contents-css'); 47 - $this->requireResource('phui-text-css'); 48 - 49 - $rows = array(); 50 - 51 - $changesets = $this->changesets; 52 - $paths = array(); 53 - foreach ($changesets as $id => $changeset) { 54 - $type = $changeset->getChangeType(); 55 - $ftype = $changeset->getFileType(); 56 - $ref = idx($this->references, $id); 57 - $display_file = $changeset->getDisplayFilename(); 58 - 59 - $meta = null; 60 - if (DifferentialChangeType::isOldLocationChangeType($type)) { 61 - $away = $changeset->getAwayPaths(); 62 - if (count($away) > 1) { 63 - $meta = array(); 64 - if ($type == DifferentialChangeType::TYPE_MULTICOPY) { 65 - $meta[] = pht('Deleted after being copied to multiple locations:'); 66 - } else { 67 - $meta[] = pht('Copied to multiple locations:'); 68 - } 69 - foreach ($away as $path) { 70 - $meta[] = $path; 71 - } 72 - $meta = phutil_implode_html(phutil_tag('br'), $meta); 73 - } else { 74 - if ($type == DifferentialChangeType::TYPE_MOVE_AWAY) { 75 - $display_file = $this->renderRename( 76 - $display_file, 77 - reset($away), 78 - "\xE2\x86\x92"); 79 - } else { 80 - $meta = pht('Copied to %s', reset($away)); 81 - } 82 - } 83 - } else if ($type == DifferentialChangeType::TYPE_MOVE_HERE) { 84 - $old_file = $changeset->getOldFile(); 85 - $display_file = $this->renderRename( 86 - $display_file, 87 - $old_file, 88 - "\xE2\x86\x90"); 89 - } else if ($type == DifferentialChangeType::TYPE_COPY_HERE) { 90 - $meta = pht('Copied from %s', $changeset->getOldFile()); 91 - } 92 - 93 - $link = $this->renderChangesetLink($changeset, $ref, $display_file); 94 - 95 - $line_count = $changeset->getAffectedLineCount(); 96 - if ($line_count == 0) { 97 - $lines = ''; 98 - } else { 99 - $lines = ' '.pht('(%d line(s))', $line_count); 100 - } 101 - 102 - $char = DifferentialChangeType::getSummaryCharacterForChangeType($type); 103 - $chartitle = DifferentialChangeType::getFullNameForChangeType($type); 104 - $desc = DifferentialChangeType::getShortNameForFileType($ftype); 105 - $color = DifferentialChangeType::getSummaryColorForChangeType($type); 106 - if ($desc) { 107 - $desc = '('.$desc.')'; 108 - } 109 - $pchar = 110 - ($changeset->getOldProperties() === $changeset->getNewProperties()) 111 - ? '' 112 - : phutil_tag( 113 - 'span', 114 - array('title' => pht('Properties Changed')), 115 - 'M'); 116 - 117 - $fname = $changeset->getFilename(); 118 - $cov = $this->renderCoverage($this->coverageMap, $fname); 119 - if ($cov === null) { 120 - $mcov = $cov = phutil_tag('em', array(), '-'); 121 - } else { 122 - $mcov = phutil_tag( 123 - 'div', 124 - array( 125 - 'id' => 'differential-mcoverage-'.md5($fname), 126 - 'class' => 'differential-mcoverage-loading', 127 - ), 128 - (isset($this->visibleChangesets[$id]) ? 129 - pht('Loading...') : pht('?'))); 130 - } 131 - 132 - if ($meta) { 133 - $meta = phutil_tag( 134 - 'div', 135 - array( 136 - 'class' => 'differential-toc-meta', 137 - ), 138 - $meta); 139 - } 140 - 141 - if ($this->diff && $this->repository) { 142 - $paths[] = 143 - $changeset->getAbsoluteRepositoryPath($this->repository, $this->diff); 144 - } 145 - 146 - $char = phutil_tag('span', array('class' => 'phui-text-'.$color), $char); 147 - 148 - $rows[] = array( 149 - $char, 150 - $pchar, 151 - $desc, 152 - array($link, $lines, $meta), 153 - $cov, 154 - $mcov, 155 - ); 156 - } 157 - 158 - $editor_link = null; 159 - if ($paths && $this->user) { 160 - $editor_link = $this->user->loadEditorLink( 161 - $paths, 162 - 1, // line number 163 - $this->repository->getCallsign()); 164 - if ($editor_link) { 165 - $editor_link = 166 - phutil_tag( 167 - 'a', 168 - array( 169 - 'href' => $editor_link, 170 - 'class' => 'button differential-toc-edit-all', 171 - ), 172 - pht('Open All in Editor')); 173 - } 174 - } 175 - 176 - $reveal_link = javelin_tag( 177 - 'a', 178 - array( 179 - 'sigil' => 'differential-reveal-all', 180 - 'mustcapture' => true, 181 - 'class' => 'button differential-toc-reveal-all', 182 - ), 183 - pht('Show All Context')); 184 - 185 - $buttons = phutil_tag( 186 - 'div', 187 - array( 188 - 'class' => 'differential-toc-buttons grouped', 189 - ), 190 - array( 191 - $editor_link, 192 - $reveal_link, 193 - )); 194 - 195 - $table = id(new AphrontTableView($rows)); 196 - $table->setHeaders( 197 - array( 198 - '', 199 - '', 200 - '', 201 - pht('Path'), 202 - pht('Coverage (All)'), 203 - pht('Coverage (Touched)'), 204 - )); 205 - $table->setColumnClasses( 206 - array( 207 - 'differential-toc-char center', 208 - 'differential-toc-prop center', 209 - 'differential-toc-ftype center', 210 - 'differential-toc-file wide', 211 - 'differential-toc-cov', 212 - 'differential-toc-cov', 213 - )); 214 - $table->setDeviceVisibility( 215 - array( 216 - true, 217 - true, 218 - true, 219 - true, 220 - false, 221 - false, 222 - )); 223 - $anchor = id(new PhabricatorAnchorView()) 224 - ->setAnchorName('toc') 225 - ->setNavigationMarker(true); 226 - 227 - return id(new PHUIObjectBoxView()) 228 - ->setHeaderText(pht('Table of Contents')) 229 - ->setTable($table) 230 - ->appendChild($anchor) 231 - ->appendChild($buttons); 232 - } 233 - 234 - private function renderRename($display_file, $other_file, $arrow) { 235 - $old = explode('/', $display_file); 236 - $new = explode('/', $other_file); 237 - 238 - $start = count($old); 239 - foreach ($old as $index => $part) { 240 - if (!isset($new[$index]) || $part != $new[$index]) { 241 - $start = $index; 242 - break; 243 - } 244 - } 245 - 246 - $end = count($old); 247 - foreach (array_reverse($old) as $from_end => $part) { 248 - $index = count($new) - $from_end - 1; 249 - if (!isset($new[$index]) || $part != $new[$index]) { 250 - $end = $from_end; 251 - break; 252 - } 253 - } 254 - 255 - $rename = 256 - '{'. 257 - implode('/', array_slice($old, $start, count($old) - $end - $start)). 258 - ' '.$arrow.' '. 259 - implode('/', array_slice($new, $start, count($new) - $end - $start)). 260 - '}'; 261 - 262 - array_splice($new, $start, count($new) - $end - $start, $rename); 263 - return implode('/', $new); 264 - } 265 - 266 - private function renderCoverage(array $coverage, $file) { 267 - $info = idx($coverage, $file); 268 - if (!$info) { 269 - return null; 270 - } 271 - 272 - $not_covered = substr_count($info, 'U'); 273 - $covered = substr_count($info, 'C'); 274 - 275 - if (!$not_covered && !$covered) { 276 - return null; 277 - } 278 - 279 - return sprintf('%d%%', 100 * ($covered / ($covered + $not_covered))); 280 - } 281 - 282 - 283 - private function renderChangesetLink( 284 - DifferentialChangeset $changeset, 285 - $ref, 286 - $display_file) { 287 - 288 - return javelin_tag( 289 - 'a', 290 - array( 291 - 'href' => '#'.$changeset->getAnchorName(), 292 - 'sigil' => 'differential-load', 293 - 'meta' => array( 294 - 'id' => 'diff-'.$changeset->getAnchorName(), 295 - ), 296 - ), 297 - $display_file); 298 - } 299 - 300 - }
+49 -30
src/applications/diffusion/controller/DiffusionCommitController.php
··· 75 75 76 76 $commit_data = $commit->getCommitData(); 77 77 $is_foreign = $commit_data->getCommitDetail('foreign-svn-stub'); 78 - $changesets = null; 79 78 if ($is_foreign) { 80 79 $subpath = $commit_data->getCommitDetail('svn-subpath'); 81 80 ··· 181 180 $user, 182 181 $this->auditAuthorityPHIDs); 183 182 184 - $owners_paths = array(); 185 - if ($highlighted_audits) { 186 - $packages = id(new PhabricatorOwnersPackage())->loadAllWhere( 187 - 'phid IN (%Ls)', 188 - mpull($highlighted_audits, 'getAuditorPHID')); 189 - if ($packages) { 190 - $owners_paths = id(new PhabricatorOwnersPath())->loadAllWhere( 191 - 'repositoryPHID = %s AND packageID IN (%Ld)', 192 - $repository->getPHID(), 193 - mpull($packages, 'getID')); 194 - } 195 - } 196 - 197 - $change_table = new DiffusionCommitChangeTableView(); 198 - $change_table->setDiffusionRequest($drequest); 199 - $change_table->setPathChanges($changes); 200 - $change_table->setOwnersPaths($owners_paths); 201 - 202 183 $count = count($changes); 203 184 204 185 $bad_commit = null; ··· 210 191 'r'.$callsign.$commit->getCommitIdentifier()); 211 192 } 212 193 194 + $show_changesets = false; 213 195 if ($bad_commit) { 214 196 $content[] = $this->renderStatusMessage( 215 197 pht('Bad Commit'), ··· 235 217 'Changes are not shown.', 236 218 $hard_limit)); 237 219 } else { 220 + $show_changesets = true; 221 + 238 222 // The user has clicked "Show All Changes", and we should show all the 239 223 // changes inline even if there are more than the soft limit. 240 224 $show_all_details = $request->getBool('show_all'); ··· 264 248 $header->addActionLink($button); 265 249 } 266 250 251 + $changesets = DiffusionPathChange::convertToDifferentialChangesets( 252 + $user, 253 + $changes); 254 + 255 + // TODO: This table and panel shouldn't really be separate, but we need 256 + // to clean up the "Load All Files" interaction first. 257 + $change_table = $this->buildTableOfContents( 258 + $changesets); 259 + 267 260 $change_panel->setTable($change_table); 268 261 $change_panel->setHeader($header); 269 262 270 263 $content[] = $change_panel; 271 - 272 - $changesets = DiffusionPathChange::convertToDifferentialChangesets( 273 - $user, 274 - $changes); 275 264 276 265 $vcs = $repository->getVersionControlSystem(); 277 266 switch ($vcs) { ··· 353 342 $change_list->setInlineCommentControllerURI( 354 343 '/diffusion/inline/edit/'.phutil_escape_uri($commit->getPHID()).'/'); 355 344 356 - $change_references = array(); 357 - foreach ($changesets as $key => $changeset) { 358 - $change_references[$changeset->getID()] = $references[$key]; 359 - } 360 - $change_table->setRenderingReferences($change_references); 361 - 362 345 $content[] = $change_list->render(); 363 346 } 364 347 ··· 375 358 $show_filetree = $prefs->getPreference($pref_filetree); 376 359 $collapsed = $prefs->getPreference($pref_collapse); 377 360 378 - if ($changesets && $show_filetree) { 361 + if ($show_changesets && $show_filetree) { 379 362 $nav = id(new DifferentialChangesetFileTreeSideNavBuilder()) 380 363 ->setTitle($short_name) 381 364 ->setBaseURI(new PhutilURI('/'.$commit_id)) ··· 1080 1063 } 1081 1064 1082 1065 return $parser->processCorpus($corpus); 1066 + } 1067 + 1068 + private function buildTableOfContents(array $changesets) { 1069 + $viewer = $this->getViewer(); 1070 + 1071 + $toc_view = id(new PHUIDiffTableOfContentsListView()) 1072 + ->setUser($viewer); 1073 + 1074 + // TODO: This is hacky, we just want access to the linkX() methods on 1075 + // DiffusionView. 1076 + $diffusion_view = id(new DiffusionEmptyResultView()) 1077 + ->setDiffusionRequest($this->getDiffusionRequest()); 1078 + 1079 + // TODO: Restore package stuff here. 1080 + 1081 + foreach ($changesets as $changeset_id => $changeset) { 1082 + $path = $changeset->getFilename(); 1083 + $anchor = substr(md5($path), 0, 8); 1084 + 1085 + $history_link = $diffusion_view->linkHistory($path); 1086 + $browse_link = $diffusion_view->linkBrowse($path); 1087 + 1088 + $item = id(new PHUIDiffTableOfContentsItemView()) 1089 + ->setChangeset($changeset) 1090 + ->setAnchor($anchor) 1091 + ->setContext( 1092 + array( 1093 + $history_link, 1094 + ' ', 1095 + $browse_link, 1096 + )); 1097 + 1098 + $toc_view->addItem($item); 1099 + } 1100 + 1101 + return $toc_view; 1083 1102 } 1084 1103 1085 1104 }
-103
src/applications/diffusion/view/DiffusionCommitChangeTableView.php
··· 1 - <?php 2 - 3 - final class DiffusionCommitChangeTableView extends DiffusionView { 4 - 5 - private $pathChanges; 6 - private $ownersPaths = array(); 7 - private $renderingReferences; 8 - 9 - public function setPathChanges(array $path_changes) { 10 - assert_instances_of($path_changes, 'DiffusionPathChange'); 11 - $this->pathChanges = $path_changes; 12 - return $this; 13 - } 14 - 15 - public function setOwnersPaths(array $owners_paths) { 16 - assert_instances_of($owners_paths, 'PhabricatorOwnersPath'); 17 - $this->ownersPaths = $owners_paths; 18 - return $this; 19 - } 20 - 21 - public function setRenderingReferences(array $value) { 22 - $this->renderingReferences = $value; 23 - return $this; 24 - } 25 - 26 - public function render() { 27 - $rows = array(); 28 - $rowc = array(); 29 - 30 - // TODO: Experiment with path stack rendering. 31 - 32 - // TODO: Copy Away and Move Away are rendered junkily still. 33 - 34 - foreach ($this->pathChanges as $id => $change) { 35 - $path = $change->getPath(); 36 - $hash = substr(md5($path), 0, 8); 37 - if ($change->getFileType() == DifferentialChangeType::FILE_DIRECTORY) { 38 - $path .= '/'; 39 - } 40 - 41 - if (isset($this->renderingReferences[$id])) { 42 - $path_column = javelin_tag( 43 - 'a', 44 - array( 45 - 'href' => '#'.$hash, 46 - 'meta' => array( 47 - 'id' => 'diff-'.$hash, 48 - 'ref' => $this->renderingReferences[$id], 49 - ), 50 - 'sigil' => 'differential-load', 51 - ), 52 - $path); 53 - } else { 54 - $path_column = $path; 55 - } 56 - 57 - $rows[] = array( 58 - $this->linkHistory($change->getPath()), 59 - $this->linkBrowse($change->getPath()), 60 - $this->linkChange( 61 - $change->getChangeType(), 62 - $change->getFileType(), 63 - $change->getPath()), 64 - $path_column, 65 - ); 66 - 67 - $row_class = null; 68 - foreach ($this->ownersPaths as $owners_path) { 69 - $excluded = $owners_path->getExcluded(); 70 - $owners_path = $owners_path->getPath(); 71 - if (strncmp('/'.$path, $owners_path, strlen($owners_path)) == 0) { 72 - if ($excluded) { 73 - $row_class = null; 74 - break; 75 - } 76 - $row_class = 'highlighted'; 77 - } 78 - } 79 - $rowc[] = $row_class; 80 - } 81 - 82 - $view = new AphrontTableView($rows); 83 - $view->setHeaders( 84 - array( 85 - pht('History'), 86 - pht('Browse'), 87 - pht('Change'), 88 - pht('Path'), 89 - )); 90 - $view->setColumnClasses( 91 - array( 92 - '', 93 - '', 94 - '', 95 - 'wide', 96 - )); 97 - $view->setRowClasses($rowc); 98 - $view->setNoDataString(pht('This change has not been fully parsed yet.')); 99 - 100 - return $view->render(); 101 - } 102 - 103 - }
+38 -3
src/infrastructure/diff/view/PHUIDiffTableOfContentsItemView.php
··· 3 3 final class PHUIDiffTableOfContentsItemView extends AphrontView { 4 4 5 5 private $changeset; 6 - private $isVisible; 6 + private $isVisible = true; 7 7 private $anchor; 8 8 private $coverage; 9 9 private $coverageID; 10 + private $context; 11 + private $package; 10 12 11 13 public function setChangeset(DifferentialChangeset $changeset) { 12 14 $this->changeset = $changeset; ··· 53 55 return $this->coverageID; 54 56 } 55 57 58 + public function setContext($context) { 59 + $this->context = $context; 60 + return $this; 61 + } 62 + 63 + public function getContext() { 64 + return $this->context; 65 + } 66 + 67 + public function setPackage(PhabricatorOwnersPackage $package) { 68 + $this->package = $package; 69 + return $this; 70 + } 71 + 72 + public function getPackage() { 73 + return $this->package; 74 + } 75 + 56 76 public function render() { 57 77 $changeset = $this->getChangeset(); 58 78 59 79 $cells = array(); 80 + 81 + $cells[] = $this->getContext(); 60 82 61 83 $cells[] = $this->renderPathChangeCharacter(); 62 84 $cells[] = $this->renderPropertyChangeCharacter(); ··· 74 96 75 97 $cells[] = $this->renderCoverage(); 76 98 $cells[] = $this->renderModifiedCoverage(); 99 + 100 + $cells[] = $this->renderPackage(); 77 101 78 102 return $cells; 79 103 } ··· 89 113 return javelin_tag( 90 114 'span', 91 115 array( 92 - 'sigil' => 'has-tip', 116 + 'sigil' => 'has-tooltip', 93 117 'meta' => array( 94 118 'tip' => $title, 95 119 'align' => 'E', ··· 112 136 return javelin_tag( 113 137 'span', 114 138 array( 115 - 'sigil' => 'has-tip', 139 + 'sigil' => 'has-tooltip', 116 140 'meta' => array( 117 141 'tip' => pht('Properties Modified'), 118 142 'align' => 'E', 143 + 'size' => 200, 119 144 ), 120 145 ), 121 146 'M'); ··· 257 282 'class' => 'differential-toc-meta', 258 283 ), 259 284 $meta); 285 + } 286 + 287 + private function renderPackage() { 288 + $package = $this->getPackage(); 289 + 290 + if (!$package) { 291 + return null; 292 + } 293 + 294 + return $this->getUser()->renderHandle($package->getPHID()); 260 295 } 261 296 262 297 private function renderRename($self, $other, $arrow) {
+42 -3
src/infrastructure/diff/view/PHUIDiffTableOfContentsListView.php
··· 14 14 $this->requireResource('differential-table-of-contents-css'); 15 15 $this->requireResource('phui-text-css'); 16 16 17 + Javelin::initBehavior('phabricator-tooltips'); 18 + 17 19 $items = $this->items; 18 20 19 21 $rows = array(); 20 22 foreach ($items as $item) { 23 + $item->setUser($this->getUser()); 21 24 $rows[] = $item->render(); 22 25 } 23 26 27 + // Check if any item has content in these columns. If no item does, we'll 28 + // just hide them. 29 + $any_coverage = false; 30 + $any_context = false; 31 + $any_package = false; 32 + foreach ($items as $item) { 33 + if ($item->getContext() !== null) { 34 + $any_context = true; 35 + } 36 + 37 + if (strlen($item->getCoverage())) { 38 + $any_coverage = true; 39 + } 40 + 41 + if ($item->getPackage() !== null) { 42 + $any_package = true; 43 + } 44 + } 45 + 24 46 $reveal_link = javelin_tag( 25 47 'a', 26 48 array( ··· 40 62 $table = id(new AphrontTableView($rows)) 41 63 ->setHeaders( 42 64 array( 43 - '', 44 - '', 45 - '', 65 + null, 66 + null, 67 + null, 68 + null, 46 69 pht('Path'), 47 70 pht('Coverage (All)'), 48 71 pht('Coverage (Touched)'), 72 + null, 49 73 )) 50 74 ->setColumnClasses( 51 75 array( 76 + 'center', 52 77 'differential-toc-char center', 53 78 'differential-toc-prop center', 54 79 'differential-toc-ftype center', 55 80 'differential-toc-file wide', 56 81 'differential-toc-cov', 57 82 'differential-toc-cov', 83 + 'center', 84 + )) 85 + ->setColumnVisibility( 86 + array( 87 + $any_context, 88 + true, 89 + true, 90 + true, 91 + true, 92 + $any_coverage, 93 + $any_coverage, 94 + $any_package, 58 95 )) 59 96 ->setDeviceVisibility( 60 97 array( ··· 62 99 true, 63 100 true, 64 101 true, 102 + true, 65 103 false, 66 104 false, 105 + true, 67 106 )); 68 107 69 108 $anchor = id(new PhabricatorAnchorView())