3 final class PhabricatorProjectPointsProfileMenuItem
4 extends PhabricatorProfileMenuItem
{
6 const MENUITEMKEY
= 'project.points';
8 public function getMenuItemTypeName() {
9 return pht('Project Points');
12 private function getDefaultName() {
13 return pht('Points Bar');
16 public function shouldEnableForObject($object) {
17 $viewer = $this->getViewer();
19 // Only render this element for milestones.
20 if (!$object->isMilestone()) {
24 // Don't show if points aren't configured.
25 if (!ManiphestTaskPoints
::getIsEnabled()) {
29 // Points are only available if Maniphest is installed.
30 $class = 'PhabricatorManiphestApplication';
31 if (!PhabricatorApplication
::isClassInstalledForViewer($class, $viewer)) {
38 public function getDisplayName(
39 PhabricatorProfileMenuItemConfiguration
$config) {
40 return $this->getDefaultName();
43 public function buildEditEngineFields(
44 PhabricatorProfileMenuItemConfiguration
$config) {
46 id(new PhabricatorInstructionsEditField())
49 'This is a progress bar which shows how many points of work '.
50 'are complete within the milestone. It has no configurable '.
55 protected function newMenuItemViewList(
56 PhabricatorProfileMenuItemConfiguration
$config) {
57 $viewer = $this->getViewer();
58 $project = $config->getProfileObject();
62 $tasks = id(new ManiphestTaskQuery())
65 PhabricatorProjectObjectHasProjectEdgeType
::EDGECONST
,
66 PhabricatorQueryConstraint
::OPERATOR_AND
,
67 array($project->getPHID()))
68 ->setLimit($limit +
1)
72 if (count($tasks) > $limit) {
75 'Too many tasks (%s).',
76 new PhutilNumber($limit));
80 $error[] = pht('This milestone has no tasks.');
87 foreach ($tasks as $task) {
88 $points = $task->getPoints();
90 if ($points === null) {
99 $status = $task->getStatus();
100 if (empty($statuses[$status])) {
101 $statuses[$status] = 0;
103 $statuses[$status] +
= $points;
105 if (ManiphestTaskStatus
::isClosedStatus($status)) {
106 $points_done +
= $points;
109 $points_total +
= $points;
112 if ($no_points == count($tasks)) {
113 $error[] = pht('No tasks have points assigned.');
116 if (!$points_total) {
117 $error[] = pht('No tasks have positive points.');
122 new PhutilNumber($points_done),
123 new PhutilNumber($points_total),
124 ManiphestTaskPoints
::getPointsLabel());
126 $bar = id(new PHUISegmentBarView())
129 $map = ManiphestTaskStatus
::getTaskStatusMap();
130 $statuses = array_select_keys($statuses, array_keys($map));
132 foreach ($statuses as $status => $points) {
137 if (!ManiphestTaskStatus
::isClosedStatus($status)) {
141 $color = ManiphestTaskStatus
::getStatusColor($status);
148 new PhutilNumber($points),
149 ManiphestTaskStatus
::getTaskStatusName($status));
152 ->setWidth($points / $points_total)
154 ->setTooltip($tooltip);
158 $bar->setLabel(head($error));
164 'class' => 'phui-profile-segment-bar',
168 $item = $this->newItemView();
170 $item->newProgressBar($bar);