diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -9,7 +9,7 @@ 'names' => array( 'conpherence.pkg.css' => '3c8a0668', 'conpherence.pkg.js' => '020aebcf', - 'core.pkg.css' => '686ae87c', + 'core.pkg.css' => '9a391b14', 'core.pkg.js' => '6e5c894f', 'differential.pkg.css' => '607c84be', 'differential.pkg.js' => '1b97518d', @@ -30,7 +30,7 @@ 'rsrc/css/aphront/notification.css' => '30240bd2', 'rsrc/css/aphront/panel-view.css' => '46923d46', 'rsrc/css/aphront/phabricator-nav-view.css' => 'f8a0c1bf', - 'rsrc/css/aphront/table-view.css' => '5f13a9e4', + 'rsrc/css/aphront/table-view.css' => '061e45eb', 'rsrc/css/aphront/tokenizer.css' => 'b52d0668', 'rsrc/css/aphront/tooltip.css' => 'e3f2412f', 'rsrc/css/aphront/typeahead-browse.css' => 'b7ed02d2', @@ -535,7 +535,7 @@ 'aphront-list-filter-view-css' => 'feb64255', 'aphront-multi-column-view-css' => 'fbc00ba3', 'aphront-panel-view-css' => '46923d46', - 'aphront-table-view-css' => '5f13a9e4', + 'aphront-table-view-css' => '061e45eb', 'aphront-tokenizer-control-css' => 'b52d0668', 'aphront-tooltip-css' => 'e3f2412f', 'aphront-typeahead-control-css' => '8779483d', diff --git a/src/applications/maniphest/controller/ManiphestTaskDetailController.php b/src/applications/maniphest/controller/ManiphestTaskDetailController.php --- a/src/applications/maniphest/controller/ManiphestTaskDetailController.php +++ b/src/applications/maniphest/controller/ManiphestTaskDetailController.php @@ -594,7 +594,8 @@ $handle_phids = array(); $any_linked = false; - $tail = array(); + $idx = 0; + $objects = array(); foreach ($commit_phids as $commit_phid) { $handle_phids[] = $commit_phid; @@ -654,16 +655,20 @@ ); } - $tail[] = array( + $objects[] = array( 'objectPHID' => $commit_phid, 'objectLink' => $object_link, 'repositoryPHID' => $repository_phid, 'revisionPHIDs' => $link_phids, 'status' => $status_view, + 'order' => id(new PhutilSortVector()) + ->addInt($repository_phid ? 1 : 0) + ->addString((string)$repository_phid) + ->addInt(1) + ->addInt($idx++), ); } - $head = array(); foreach ($revision_phids as $revision_phid) { $handle_phids[] = $revision_phid; @@ -717,20 +722,44 @@ ); } - $head[] = array( + $objects[] = array( 'objectPHID' => $revision_phid, 'objectLink' => $object_link, 'repositoryPHID' => $repository_phid, 'revisionPHIDs' => array(), 'status' => $status_view, + 'order' => id(new PhutilSortVector()) + ->addInt($repository_phid ? 1 : 0) + ->addString((string)$repository_phid) + ->addInt(0) + ->addInt($idx++), ); } - $objects = array_merge($head, $tail); $handles = $viewer->loadHandles($handle_phids); + $order = ipull($objects, 'order'); + $order = msortv($order, 'getSelf'); + $objects = array_select_keys($objects, array_keys($order)); + + $last_repository = false; $rows = array(); + $rowd = array(); foreach ($objects as $object) { + $repository_phid = $object['repositoryPHID']; + if ($repository_phid !== $last_repository) { + $repository_link = null; + if ($repository_phid) { + $repository_link = $handles[$repository_phid]->renderLink(); + $rows[] = array( + $repository_link, + ); + $rowd[] = true; + } + + $last_repository = $repository_phid; + } + $object_phid = $object['objectPHID']; $handle = $handles[$object_phid]; @@ -742,12 +771,6 @@ $object_icon = id(new PHUIIconView()) ->setIcon($handle->getIcon()); - $repository_link = null; - $repository_phid = $object['repositoryPHID']; - if ($repository_phid) { - $repository_link = $handles[$repository_phid]->renderLink(); - } - $status_view = $object['status']; $revision_tags = array(); @@ -762,10 +785,10 @@ phutil_tag('br'), $revision_tags); + $rowd[] = false; $rows[] = array( $object_icon, $status_view, - $repository_link, $revision_tags, $object_link, ); @@ -773,11 +796,11 @@ $changes_table = id(new AphrontTableView($rows)) ->setNoDataString(pht('This task has no related commits or revisions.')) + ->setRowDividers($rowd) ->setHeaders( array( null, null, - pht('Repository'), null, pht('Revision/Commit'), )) @@ -786,12 +809,10 @@ 'center', null, null, - null, 'wide pri object-link', )) ->setColumnVisibility( array( - true, true, true, $any_linked, @@ -802,7 +823,6 @@ false, true, false, - false, true, )); diff --git a/src/view/control/AphrontTableView.php b/src/view/control/AphrontTableView.php --- a/src/view/control/AphrontTableView.php +++ b/src/view/control/AphrontTableView.php @@ -24,6 +24,8 @@ protected $sortValues = array(); private $deviceReadyTable; + private $rowDividers = array(); + public function __construct(array $data) { $this->data = $data; } @@ -53,6 +55,11 @@ return $this; } + public function setRowDividers(array $dividers) { + $this->rowDividers = $dividers; + return $this; + } + public function setNoDataString($no_data_string) { $this->noDataString = $no_data_string; return $this; @@ -258,10 +265,15 @@ } } + $dividers = $this->rowDividers; + $data = $this->data; if ($data) { $row_num = 0; + $row_idx = 0; foreach ($data as $row) { + $is_divider = !empty($dividers[$row_num]); + $row_size = count($row); while (count($row) > count($col_classes)) { $col_classes[] = null; @@ -289,6 +301,18 @@ $class = trim($class.' '.$this->cellClasses[$row_num][$col_num]); } + if ($is_divider) { + $tr[] = phutil_tag( + 'td', + array( + 'class' => 'row-divider', + 'colspan' => count($headers), + ), + $value); + $row_idx = -1; + break; + } + $tr[] = phutil_tag( 'td', array( @@ -299,7 +323,7 @@ } $class = idx($this->rowClasses, $row_num); - if ($this->zebraStripes && ($row_num % 2)) { + if ($this->zebraStripes && ($row_idx % 2)) { if ($class !== null) { $class = 'alt alt-'.$class; } else { @@ -309,6 +333,7 @@ $table[] = phutil_tag('tr', array('class' => $class), $tr); ++$row_num; + ++$row_idx; } } else { $colspan = max(count(array_filter($visibility)), 1); diff --git a/webroot/rsrc/css/aphront/table-view.css b/webroot/rsrc/css/aphront/table-view.css --- a/webroot/rsrc/css/aphront/table-view.css +++ b/webroot/rsrc/css/aphront/table-view.css @@ -55,6 +55,12 @@ background-color: {$lightbluebackground}; } +.aphront-table-view td.row-divider { + background-color: {$bluebackground}; + font-weight: bold; + padding: 8px 12px; +} + .aphront-table-view th { border-bottom: 1px solid {$thinblueborder}; }