Commit 9f52d13e authored by Daniel Stone's avatar Daniel Stone Committed by Ana Rute Mendes
Browse files

LOCAL/UI: Project: Show review/CI status on workboard

On project workboard cards, also show the status of linked code reviews;
both the review itself, and any attached Harbormaster CI buildables.

This is already taken care of in the task-detail view by 45c740ac,
and extends it to the workboard view. It should probably share more code
with the task-detail view.

It will not be accepted upstream in its current form; it was felt in
https://secure.phabricator.com/T7076 discussion that performing multiple
queries for each revision to get the current state was too much. This
makes it exceedingly unlikely that doing the same number of queries for
every task in a workboard would be acceptable.

There was discussion of how to fix that, but it was essentially
impossible, and explicitly discouraged for anyone to even try.
parent 2f44c0bf
......@@ -49,6 +49,7 @@ final class ManiphestTask extends ManiphestDAO
protected $closedEpoch;
protected $closerPHID;
private $revisions = null;
private $subscriberPHIDs = self::ATTACHABLE;
private $groupByProjectPHID = self::ATTACHABLE;
......@@ -161,6 +162,27 @@ final class ManiphestTask extends ManiphestDAO
ManiphestTaskDependedOnByTaskEdgeType::EDGECONST);
}
public function loadRevisions(PhabricatorUser $viewer) {
if ($this->revisions) {
return;
}
$phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
$this->getPHID(),
ManiphestTaskHasRevisionEdgeType::EDGECONST);
if (count($phids) == 0) {
$this->revisions = array();
return;
}
$this->revisions = id(new DifferentialRevisionQuery())
->setViewer($viewer)
->setOrder(DifferentialRevisionQuery::ORDER_CREATED)
->withPHIDs($phids)
->execute();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(ManiphestTaskPHIDType::TYPECONST);
}
......@@ -259,6 +281,119 @@ final class ManiphestTask extends ManiphestDAO
return ManiphestTaskPriority::UNKNOWN_PRIORITY_KEYWORD;
}
private function comparePriorityTo(ManiphestTask $other) {
$upri = $this->getPriority();
$vpri = $other->getPriority();
if ($upri != $vpri) {
return ($upri - $vpri);
}
$usub = $this->getSubpriority();
$vsub = $other->getSubpriority();
if ($usub != $vsub) {
return ($usub - $vsub);
}
$uid = $this->getID();
$vid = $other->getID();
if ($uid != $vid) {
return ($uid - $vid);
}
return 0;
}
public function isLowerPriorityThan(ManiphestTask $other) {
return ($this->comparePriorityTo($other) < 0);
}
public function isHigherPriorityThan(ManiphestTask $other) {
return ($this->comparePriorityTo($other) > 0);
}
public function getWorkboardProperties() {
return array(
'status' => $this->getStatus(),
'points' => (double)$this->getPoints(),
);
}
public function getReviewIcon(PhabricatorUser $viewer) {
// Determine an overall review/CI status for the task, pessimising heavily
// as we do so. Discount abandoned reviews as irrelevant, then proceed
// in the following order: needs revision, changes planned, needs review,
// in preparation, accepted, closed.
$priorities = array(
DifferentialRevisionStatus::NEEDS_REVISION => 5,
DifferentialRevisionStatus::CHANGES_PLANNED => 4,
DifferentialRevisionStatus::NEEDS_REVIEW => 3,
DifferentialRevisionStatus::ACCEPTED => 1,
DifferentialRevisionStatus::PUBLISHED => 0,
DifferentialRevisionStatus::ABANDONED => -1,
DifferentialRevisionStatus::DRAFT => -1,
);
$ci_diff_map = array(
HarbormasterBuildableStatus::STATUS_PREPARING =>
DifferentialRevisionStatus::NEEDS_REVIEW,
HarbormasterBuildableStatus::STATUS_BUILDING =>
DifferentialRevisionStatus::NEEDS_REVIEW,
HarbormasterBuildableStatus::STATUS_PASSED =>
DifferentialRevisionStatus::ACCEPTED,
HarbormasterBuildableStatus::STATUS_FAILED =>
DifferentialRevisionStatus::NEEDS_REVISION,
);
$status = DifferentialRevisionStatus::ABANDONED;
$this->loadRevisions($viewer);
if (count($this->revisions) == 0) {
return null;
}
foreach ($this->revisions as $revision) {
$rev_status = $revision->getStatus();
$diff = $revision->loadActiveDiff();
if ($diff) {
$buildables = id(new HarbormasterBuildableQuery())
->setViewer($viewer)
->withBuildablePHIDs(array($diff->getPHID()))
->withManualBuildables(true)
->needBuilds(true)
->needTargets(true)
->execute();
foreach ($buildables as $buildable) {
$ci_status = $ci_diff_map[$buildable->getStatus()];
if ($ci_status > $rev_status) {
$rev_status = $ci_status;
}
}
}
if ($priorities[$rev_status] >
$priorities[$status]) {
$status = $rev_status;
}
}
switch ($status) {
case ArcanistDifferentialRevisionStatus::ABANDONED:
return null;
case ArcanistDifferentialRevisionStatus::NEEDS_REVISION:
case ArcanistDifferentialRevisionStatus::CHANGES_PLANNED:
return 'fa-frown-o red';
case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW:
case ArcanistDifferentialRevisionStatus::IN_PREPARATION:
return 'fa-meh-o darkgrey';
case ArcanistDifferentialRevisionStatus::ACCEPTED:
case ArcanistDifferentialRevisionStatus::CLOSED:
return 'fa-smile-o green';
}
}
/* -( PhabricatorSubscribableInterface )----------------------------------- */
......
......@@ -157,6 +157,15 @@ final class ProjectBoardTaskCard extends Phobject {
$card->setBarColor('grey');
}
$review_status = $task->getReviewIcon($viewer);
if ($review_status) {
$review_tag = id(new PHUITagView())
->setType(PHUITagView::TYPE_OBJECT)
->setBackgroundColor(null)
->setIcon($review_status);
$card->addAttribute($review_tag);
}
$project_handles = $this->getProjectHandles();
// Remove any archived or hidden projects from the list.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment