diff --git a/src/applications/differential/constants/DifferentialRevisionStatus.php b/src/applications/differential/constants/DifferentialRevisionStatus.php index b4b291f9c4..70f0e33b28 100644 --- a/src/applications/differential/constants/DifferentialRevisionStatus.php +++ b/src/applications/differential/constants/DifferentialRevisionStatus.php @@ -8,6 +8,7 @@ final class DifferentialRevisionStatus extends Phobject { const ACCEPTED = 'accepted'; const PUBLISHED = 'published'; const ABANDONED = 'abandoned'; + const DRAFT = 'draft'; private $key; private $spec = array(); @@ -76,6 +77,10 @@ final class DifferentialRevisionStatus extends Phobject { return ($this->key === self::CHANGES_PLANNED); } + public function isDraft() { + return ($this->key === self::DRAFT); + } + public static function newForStatus($status) { $result = new self(); @@ -163,6 +168,16 @@ final class DifferentialRevisionStatus extends Phobject { 'color.tag' => 'indigo', 'color.ansi' => null, ), + self::DRAFT => array( + 'name' => pht('Draft'), + // For legacy clients, treat this as though it is "Needs Review". + 'legacy' => 0, + 'icon' => 'fa-file-text-o', + 'closed' => false, + 'color.icon' => 'grey', + 'color.tag' => 'grey', + 'color.ansi' => null, + ), ); } diff --git a/src/applications/differential/query/DifferentialRevisionRequiredActionResultBucket.php b/src/applications/differential/query/DifferentialRevisionRequiredActionResultBucket.php index 195a430b1c..f3971f8571 100644 --- a/src/applications/differential/query/DifferentialRevisionRequiredActionResultBucket.php +++ b/src/applications/differential/query/DifferentialRevisionRequiredActionResultBucket.php @@ -37,6 +37,9 @@ final class DifferentialRevisionRequiredActionResultBucket // other project or package reviewers which they have authority over. $this->filterResigned($phids); + // We also throw away draft revisions which you aren't the author of. + $this->filterOtherDrafts($phids); + $groups = array(); $groups[] = $this->newGroup() @@ -61,6 +64,11 @@ final class DifferentialRevisionRequiredActionResultBucket ->setNoDataString(pht('No revisions are waiting for updates.')) ->setObjects($this->filterShouldUpdate($phids)); + $groups[] = $this->newGroup() + ->setName(pht('Drafts')) + ->setNoDataString(pht('You have no draft revisions.')) + ->setObjects($this->filterDrafts($phids)); + $groups[] = $this->newGroup() ->setName(pht('Waiting on Review')) ->setNoDataString(pht('None of your revisions are waiting on review.')) @@ -247,4 +255,36 @@ final class DifferentialRevisionRequiredActionResultBucket return $results; } + private function filterOtherDrafts(array $phids) { + $objects = $this->getRevisionsNotAuthored($this->objects, $phids); + + $results = array(); + foreach ($objects as $key => $object) { + if (!$object->isDraft()) { + continue; + } + + $results[$key] = $object; + unset($this->objects[$key]); + } + + return $results; + } + + private function filterDrafts(array $phids) { + $objects = $this->getRevisionsAuthored($this->objects, $phids); + + $results = array(); + foreach ($objects as $key => $object) { + if (!$object->isDraft()) { + continue; + } + + $results[$key] = $object; + unset($this->objects[$key]); + } + + return $results; + } + } diff --git a/src/applications/differential/storage/DifferentialRevision.php b/src/applications/differential/storage/DifferentialRevision.php index 3615c6e78b..03602b49d9 100644 --- a/src/applications/differential/storage/DifferentialRevision.php +++ b/src/applications/differential/storage/DifferentialRevision.php @@ -653,6 +653,10 @@ final class DifferentialRevision extends DifferentialDAO return $this->getStatusObject()->isPublished(); } + public function isDraft() { + return $this->getStatusObject()->isDraft(); + } + public function getStatusIcon() { return $this->getStatusObject()->getIcon(); }