mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-18 18:51:12 +01:00
Use new Differential bucketing logic on default (non-dashboard) homepage
Summary: Ref T10939. If you haven't installed a dashboard, we show an "Active Revisions" panel on the homepage by default. I waited a bit to update this, but the new buckets don't seem to have caused any major problems so far. Update this to use the new logic. I'm just showing "must review" + "should review", which is similar to the old beahvior. Also replace the notification count with this same number. This is a little different from the old behavior, but simpler, and I think we should probably move toward getting rid of these counts completely. Test Plan: - Viewed homepage as logged-in user, saw my revisions (including revisions I have authority over only because of project membership). - Saw consistent notification count. - Grepped for removed method. Reviewers: chad Reviewed By: chad Maniphest Tasks: T10939 Differential Revision: https://secure.phabricator.com/D15950
This commit is contained in:
parent
0fad384727
commit
7ae33d14ec
5 changed files with 90 additions and 120 deletions
|
@ -102,68 +102,78 @@ final class PhabricatorDifferentialApplication extends PhabricatorApplication {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function loadNeedAttentionRevisions(PhabricatorUser $viewer) {
|
||||||
|
if (!$viewer->isLoggedIn()) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$viewer_phid = $viewer->getPHID();
|
||||||
|
|
||||||
|
$responsible_phids = id(new DifferentialResponsibleDatasource())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->evaluateTokens(array($viewer_phid));
|
||||||
|
|
||||||
|
$revision_query = id(new DifferentialRevisionQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withStatus(DifferentialRevisionQuery::STATUS_OPEN)
|
||||||
|
->withResponsibleUsers($responsible_phids)
|
||||||
|
->needReviewerStatus(true)
|
||||||
|
->needRelationships(true)
|
||||||
|
->needFlags(true)
|
||||||
|
->needDrafts(true)
|
||||||
|
->setLimit(self::MAX_STATUS_ITEMS);
|
||||||
|
|
||||||
|
$revisions = $revision_query->execute();
|
||||||
|
|
||||||
|
$query = id(new PhabricatorSavedQuery())
|
||||||
|
->attachParameterMap(
|
||||||
|
array(
|
||||||
|
'responsiblePHIDs' => $responsible_phids,
|
||||||
|
));
|
||||||
|
|
||||||
|
$groups = id(new DifferentialRevisionRequiredActionResultBucket())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->newResultGroups($query, $revisions);
|
||||||
|
|
||||||
|
$include = array();
|
||||||
|
foreach ($groups as $group) {
|
||||||
|
switch ($group->getKey()) {
|
||||||
|
case DifferentialRevisionRequiredActionResultBucket::KEY_MUSTREVIEW:
|
||||||
|
case DifferentialRevisionRequiredActionResultBucket::KEY_SHOULDREVIEW:
|
||||||
|
foreach ($group->getObjects() as $object) {
|
||||||
|
$include[] = $object;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $include;
|
||||||
|
}
|
||||||
|
|
||||||
public function loadStatus(PhabricatorUser $user) {
|
public function loadStatus(PhabricatorUser $user) {
|
||||||
|
$revisions = self::loadNeedAttentionRevisions($user);
|
||||||
$limit = self::MAX_STATUS_ITEMS;
|
$limit = self::MAX_STATUS_ITEMS;
|
||||||
|
|
||||||
$revisions = id(new DifferentialRevisionQuery())
|
if (count($revisions) >= $limit) {
|
||||||
->setViewer($user)
|
$display_count = ($limit - 1);
|
||||||
->withResponsibleUsers(array($user->getPHID()))
|
$display_label = pht(
|
||||||
->withStatus(DifferentialRevisionQuery::STATUS_OPEN)
|
'%s+ Active Review(s)',
|
||||||
->needRelationships(true)
|
new PhutilNumber($display_count));
|
||||||
->setLimit($limit)
|
} else {
|
||||||
->execute();
|
$display_count = count($revisions);
|
||||||
|
$display_label = pht(
|
||||||
|
'%s Review(s) Need Attention',
|
||||||
|
new PhutilNumber($display_count));
|
||||||
|
}
|
||||||
|
|
||||||
$status = array();
|
$status = array();
|
||||||
if (count($revisions) >= $limit) {
|
|
||||||
$all_count = count($revisions);
|
|
||||||
$all_count_str = pht(
|
|
||||||
'%s+ Active Review(s)',
|
|
||||||
new PhutilNumber($limit - 1));
|
|
||||||
|
|
||||||
$type = PhabricatorApplicationStatusView::TYPE_WARNING;
|
|
||||||
$status[] = id(new PhabricatorApplicationStatusView())
|
$status[] = id(new PhabricatorApplicationStatusView())
|
||||||
->setType($type)
|
->setType(PhabricatorApplicationStatusView::TYPE_WARNING)
|
||||||
->setText($all_count_str)
|
->setText($display_label)
|
||||||
->setCount($all_count);
|
->setCount($display_count);
|
||||||
} else {
|
|
||||||
list($blocking, $active, $waiting) =
|
|
||||||
DifferentialRevisionQuery::splitResponsible(
|
|
||||||
$revisions,
|
|
||||||
array($user->getPHID()));
|
|
||||||
|
|
||||||
$blocking = count($blocking);
|
|
||||||
$blocking_str = pht(
|
|
||||||
'%s Review(s) Blocking Others',
|
|
||||||
new PhutilNumber($blocking));
|
|
||||||
|
|
||||||
$type = PhabricatorApplicationStatusView::TYPE_NEEDS_ATTENTION;
|
|
||||||
$status[] = id(new PhabricatorApplicationStatusView())
|
|
||||||
->setType($type)
|
|
||||||
->setText($blocking_str)
|
|
||||||
->setCount($blocking);
|
|
||||||
|
|
||||||
$active = count($active);
|
|
||||||
$active_str = pht(
|
|
||||||
'%s Review(s) Need Attention',
|
|
||||||
new PhutilNumber($active));
|
|
||||||
|
|
||||||
$type = PhabricatorApplicationStatusView::TYPE_WARNING;
|
|
||||||
$status[] = id(new PhabricatorApplicationStatusView())
|
|
||||||
->setType($type)
|
|
||||||
->setText($active_str)
|
|
||||||
->setCount($active);
|
|
||||||
|
|
||||||
$waiting = count($waiting);
|
|
||||||
$waiting_str = pht(
|
|
||||||
'%s Review(s) Waiting on Others',
|
|
||||||
new PhutilNumber($waiting));
|
|
||||||
|
|
||||||
$type = PhabricatorApplicationStatusView::TYPE_INFO;
|
|
||||||
$status[] = id(new PhabricatorApplicationStatusView())
|
|
||||||
->setType($type)
|
|
||||||
->setText($waiting_str)
|
|
||||||
->setCount($waiting);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $status;
|
return $status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1033,50 +1033,6 @@ final class DifferentialRevisionQuery
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static function splitResponsible(array $revisions, array $user_phids) {
|
|
||||||
$blocking = array();
|
|
||||||
$active = array();
|
|
||||||
$waiting = array();
|
|
||||||
$status_review = ArcanistDifferentialRevisionStatus::NEEDS_REVIEW;
|
|
||||||
|
|
||||||
// Bucket revisions into $blocking (revisions where you are blocking
|
|
||||||
// others), $active (revisions you need to do something about) and $waiting
|
|
||||||
// (revisions you're waiting on someone else to do something about).
|
|
||||||
foreach ($revisions as $revision) {
|
|
||||||
$needs_review = ($revision->getStatus() == $status_review);
|
|
||||||
$filter_is_author = in_array($revision->getAuthorPHID(), $user_phids);
|
|
||||||
if (!$revision->getReviewers()) {
|
|
||||||
$needs_review = false;
|
|
||||||
$author_is_reviewer = false;
|
|
||||||
} else {
|
|
||||||
$author_is_reviewer = in_array(
|
|
||||||
$revision->getAuthorPHID(),
|
|
||||||
$revision->getReviewers());
|
|
||||||
}
|
|
||||||
|
|
||||||
// If exactly one of "needs review" and "the user is the author" is
|
|
||||||
// true, the user needs to act on it. Otherwise, they're waiting on
|
|
||||||
// it.
|
|
||||||
if ($needs_review ^ $filter_is_author) {
|
|
||||||
if ($needs_review) {
|
|
||||||
array_unshift($blocking, $revision);
|
|
||||||
} else {
|
|
||||||
$active[] = $revision;
|
|
||||||
}
|
|
||||||
// User is author **and** reviewer. An exotic but configurable workflow.
|
|
||||||
// User needs to act on it double.
|
|
||||||
} else if ($needs_review && $author_is_reviewer) {
|
|
||||||
array_unshift($blocking, $revision);
|
|
||||||
$active[] = $revision;
|
|
||||||
} else {
|
|
||||||
$waiting[] = $revision;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return array($blocking, $active, $waiting);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function loadReviewerAuthority(
|
private function loadReviewerAuthority(
|
||||||
array $revisions,
|
array $revisions,
|
||||||
array $edges,
|
array $edges,
|
||||||
|
|
|
@ -5,6 +5,9 @@ final class DifferentialRevisionRequiredActionResultBucket
|
||||||
|
|
||||||
const BUCKETKEY = 'action';
|
const BUCKETKEY = 'action';
|
||||||
|
|
||||||
|
const KEY_MUSTREVIEW = 'must-review';
|
||||||
|
const KEY_SHOULDREVIEW = 'should-review';
|
||||||
|
|
||||||
private $objects;
|
private $objects;
|
||||||
|
|
||||||
public function getResultBucketName() {
|
public function getResultBucketName() {
|
||||||
|
@ -30,11 +33,13 @@ final class DifferentialRevisionRequiredActionResultBucket
|
||||||
|
|
||||||
$groups[] = $this->newGroup()
|
$groups[] = $this->newGroup()
|
||||||
->setName(pht('Must Review'))
|
->setName(pht('Must Review'))
|
||||||
|
->setKey(self::KEY_MUSTREVIEW)
|
||||||
->setNoDataString(pht('No revisions are blocked on your review.'))
|
->setNoDataString(pht('No revisions are blocked on your review.'))
|
||||||
->setObjects($this->filterMustReview($phids));
|
->setObjects($this->filterMustReview($phids));
|
||||||
|
|
||||||
$groups[] = $this->newGroup()
|
$groups[] = $this->newGroup()
|
||||||
->setName(pht('Ready to Review'))
|
->setName(pht('Ready to Review'))
|
||||||
|
->setKey(self::KEY_SHOULDREVIEW)
|
||||||
->setNoDataString(pht('No revisions are waiting on you to review them.'))
|
->setNoDataString(pht('No revisions are waiting on you to review them.'))
|
||||||
->setObjects($this->filterShouldReview($phids));
|
->setObjects($this->filterShouldReview($phids));
|
||||||
|
|
||||||
|
|
|
@ -205,40 +205,29 @@ final class PhabricatorHomeMainController extends PhabricatorHomeController {
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildRevisionPanel() {
|
private function buildRevisionPanel() {
|
||||||
$user = $this->getRequest()->getUser();
|
$viewer = $this->getViewer();
|
||||||
$user_phid = $user->getPHID();
|
|
||||||
|
|
||||||
$revision_query = id(new DifferentialRevisionQuery())
|
$revisions = PhabricatorDifferentialApplication::loadNeedAttentionRevisions(
|
||||||
->setViewer($user)
|
$viewer);
|
||||||
->withStatus(DifferentialRevisionQuery::STATUS_OPEN)
|
|
||||||
->withResponsibleUsers(array($user_phid))
|
|
||||||
->needRelationships(true)
|
|
||||||
->needFlags(true)
|
|
||||||
->needDrafts(true);
|
|
||||||
|
|
||||||
$revisions = $revision_query->execute();
|
if (!$revisions) {
|
||||||
|
|
||||||
list($blocking, $active) = DifferentialRevisionQuery::splitResponsible(
|
|
||||||
$revisions,
|
|
||||||
array($user_phid));
|
|
||||||
|
|
||||||
if (!$blocking && !$active) {
|
|
||||||
return $this->renderMiniPanel(
|
return $this->renderMiniPanel(
|
||||||
pht('No Waiting Revisions'),
|
pht('No Waiting Revisions'),
|
||||||
pht('No revisions are waiting on you.'));
|
pht('No revisions are waiting on you.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$title = pht('Revisions Waiting on You');
|
$title = pht('Revisions Waiting on You');
|
||||||
$href = '/differential';
|
$href = '/differential/';
|
||||||
$panel = new PHUIObjectBoxView();
|
$panel = new PHUIObjectBoxView();
|
||||||
$panel->setHeader($this->renderSectionHeader($title, $href));
|
$panel->setHeader($this->renderSectionHeader($title, $href));
|
||||||
|
|
||||||
$revision_view = id(new DifferentialRevisionListView())
|
$revision_view = id(new DifferentialRevisionListView())
|
||||||
->setHighlightAge(true)
|
->setHighlightAge(true)
|
||||||
->setRevisions(array_merge($blocking, $active))
|
->setRevisions($revisions)
|
||||||
->setUser($user);
|
->setUser($viewer);
|
||||||
|
|
||||||
$phids = array_merge(
|
$phids = array_merge(
|
||||||
array($user_phid),
|
array($viewer->getPHID()),
|
||||||
$revision_view->getRequiredHandlePHIDs());
|
$revision_view->getRequiredHandlePHIDs());
|
||||||
$handles = $this->loadViewerHandles($phids);
|
$handles = $this->loadViewerHandles($phids);
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ final class PhabricatorSearchResultBucketGroup
|
||||||
extends Phobject {
|
extends Phobject {
|
||||||
|
|
||||||
private $name;
|
private $name;
|
||||||
|
private $key;
|
||||||
private $noDataString;
|
private $noDataString;
|
||||||
private $objects;
|
private $objects;
|
||||||
|
|
||||||
|
@ -25,6 +26,15 @@ final class PhabricatorSearchResultBucketGroup
|
||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setKey($key) {
|
||||||
|
$this->key = $key;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getKey() {
|
||||||
|
return $this->key;
|
||||||
|
}
|
||||||
|
|
||||||
public function setObjects(array $objects) {
|
public function setObjects(array $objects) {
|
||||||
$this->objects = $objects;
|
$this->objects = $objects;
|
||||||
return $this;
|
return $this;
|
||||||
|
|
Loading…
Reference in a new issue