4 * Render a table of Differential revisions.
6 final class DifferentialRevisionListView
extends AphrontView
{
8 private $revisions = array();
10 private $noDataString;
12 private $background = null;
13 private $unlandedDependencies = array();
15 public function setUnlandedDependencies(array $unlanded_dependencies) {
16 $this->unlandedDependencies
= $unlanded_dependencies;
20 public function getUnlandedDependencies() {
21 return $this->unlandedDependencies
;
24 public function setNoDataString($no_data_string) {
25 $this->noDataString
= $no_data_string;
29 public function setHeader($header) {
30 $this->header
= $header;
34 public function setRevisions(array $revisions) {
35 assert_instances_of($revisions, 'DifferentialRevision');
36 $this->revisions
= $revisions;
40 public function setNoBox($box) {
45 public function setBackground($background) {
46 $this->background
= $background;
50 public function render() {
51 $viewer = $this->getViewer();
53 $this->initBehavior('phabricator-tooltips', array());
54 $this->requireResource('aphront-tooltip-css');
58 $reviewer_phids = array();
59 $reviewer_more = array();
60 $handle_phids = array();
61 foreach ($this->revisions
as $key => $revision) {
62 $reviewers = $revision->getReviewers();
64 // Don't show reviewers who have resigned. The "Reviewers" constraint
65 // does not respect these reviewers and they largely don't count as
67 foreach ($reviewers as $reviewer_key => $reviewer) {
68 if ($reviewer->isResigned()) {
69 unset($reviewers[$reviewer_key]);
73 if (count($reviewers) > $reviewer_limit) {
74 $reviewers = array_slice($reviewers, 0, $reviewer_limit);
75 $reviewer_more[$key] = true;
77 $reviewer_more[$key] = false;
80 $phids = mpull($reviewers, 'getReviewerPHID');
82 $reviewer_phids[$key] = $phids;
83 foreach ($phids as $phid) {
84 $handle_phids[$phid] = $phid;
87 $author_phid = $revision->getAuthorPHID();
88 $handle_phids[$author_phid] = $author_phid;
91 $handles = $viewer->loadHandles($handle_phids);
93 $list = new PHUIObjectItemListView();
94 foreach ($this->revisions
as $key => $revision) {
95 $item = id(new PHUIObjectItemView())
100 $phid = $revision->getPHID();
101 $flag = $revision->getFlag($viewer);
103 $flag_class = PhabricatorFlagColor
::getCSSClass($flag->getColor());
104 $icons['flag'] = phutil_tag(
107 'class' => 'phabricator-flag-icon '.$flag_class,
112 $modified = $revision->getDateModified();
114 if (isset($icons['flag'])) {
115 $item->addHeadIcon($icons['flag']);
118 $item->setObjectName($revision->getMonogram());
119 $item->setHeader($revision->getTitle());
120 $item->setHref($revision->getURI());
122 $size = $this->renderRevisionSize($revision);
123 if ($size !== null) {
124 $item->addAttribute($size);
127 if ($revision->getHasDraft($viewer)) {
128 $draft = id(new PHUIIconView())
129 ->setIcon('fa-comment yellow')
130 ->addSigil('has-tooltip')
133 'tip' => pht('Unsubmitted Comments'),
135 $item->addAttribute($draft);
138 $author_handle = $handles[$revision->getAuthorPHID()];
139 $item->addByline(pht('Author: %s', $author_handle->renderLink()));
141 $unlanded = idx($this->unlandedDependencies
, $phid);
145 id(new PHUIIconView())->setIcon('fa-chain-broken', 'red'),
147 pht('Open Dependencies'),
152 if ($reviewer_more[$key]) {
153 $more = pht(', ...');
158 if ($reviewer_phids[$key]) {
163 $viewer->renderHandleList($reviewer_phids[$key])
168 $item->addAttribute(phutil_tag('em', array(), pht('No Reviewers')));
171 $item->setEpoch($revision->getDateModified());
173 if ($revision->isClosed()) {
174 $item->setDisabled(true);
177 $icon = $revision->getStatusIcon();
178 $color = $revision->getStatusIconColor();
180 $item->setStatusIcon(
182 $revision->getStatusDisplayName());
184 $list->addItem($item);
187 $list->setNoDataString($this->noDataString
);
190 if ($this->header
&& !$this->noBox
) {
191 $list->setFlush(true);
192 $list = id(new PHUIObjectBoxView())
193 ->setBackground($this->background
)
194 ->setObjectList($list);
196 if ($this->header
instanceof PHUIHeaderView
) {
197 $list->setHeader($this->header
);
199 $list->setHeaderText($this->header
);
202 $list->setHeader($this->header
);
208 private function renderRevisionSize(DifferentialRevision
$revision) {
209 if (!$revision->hasLineCounts()) {
215 $glyphs = $revision->getRevisionScaleGlyphs();
217 for ($ii = 0; $ii < 7; $ii++
) {
222 $size[] = id(new PHUIIconView())
223 ->setIcon('fa-plus');
227 $size[] = id(new PHUIIconView())
228 ->setIcon('fa-minus');
231 $size[] = id(new PHUIIconView())
232 ->setIcon('fa-square-o invisible');
237 $n = $revision->getAddedLineCount() +
$revision->getRemovedLineCount();
240 $classes[] = 'differential-revision-size';
243 $tip[] = pht('%s Lines', new PhutilNumber($n));
245 if ($plus_count <= 1) {
246 $classes[] = 'differential-revision-small';
247 $tip[] = pht('Smaller Change');
250 if ($plus_count >= 4) {
251 $classes[] = 'differential-revision-large';
252 $tip[] = pht('Larger Change');
255 $tip = phutil_implode_html(" \xC2\xB7 ", $tip);
260 'class' => implode(' ', $classes),
261 'sigil' => 'has-tooltip',