private function handlePropertyEvent($ui_event)
 {
     $user = $ui_event->getUser();
     $object = $ui_event->getValue('object');
     if (!$object || !$object->getPHID()) {
         // No object, or the object has no PHID yet..
         return;
     }
     if ($object instanceof HarbormasterBuildable) {
         // Although HarbormasterBuildable implements the correct interface, it
         // does not make sense to show a build's build status. In the best case
         // it is meaningless, and in the worst case it's confusing.
         return;
     }
     if ($object instanceof DifferentialRevision) {
         // TODO: This is a bit hacky and we could probably find a cleaner fix
         // eventually, but we show build status on each diff, immediately below
         // this property list, so it's redundant to show it on the revision view.
         return;
     }
     if (!$object instanceof HarbormasterBuildableInterface) {
         return;
     }
     $buildable_phid = $object->getHarbormasterBuildablePHID();
     if (!$buildable_phid) {
         return;
     }
     if (!$this->canUseApplication($ui_event->getUser())) {
         return;
     }
     $buildable = id(new HarbormasterBuildableQuery())->setViewer($user)->withManualBuildables(false)->withBuildablePHIDs(array($buildable_phid))->needBuilds(true)->executeOne();
     if (!$buildable) {
         return;
     }
     $builds = $buildable->getBuilds();
     $build_handles = id(new PhabricatorHandleQuery())->setViewer($user)->withPHIDs(mpull($builds, 'getPHID'))->execute();
     $status_view = new PHUIStatusListView();
     $buildable_status = $buildable->getBuildableStatus();
     $buildable_icon = HarbormasterBuildable::getBuildableStatusIcon($buildable_status);
     $buildable_color = HarbormasterBuildable::getBuildableStatusColor($buildable_status);
     $buildable_name = HarbormasterBuildable::getBuildableStatusName($buildable_status);
     $target = phutil_tag('a', array('href' => '/' . $buildable->getMonogram()), pht('Buildable %d', $buildable->getID()));
     $target = phutil_tag('strong', array(), $target);
     $status_view->addItem(id(new PHUIStatusItemView())->setIcon($buildable_icon, $buildable_color, $buildable_name)->setTarget($target));
     foreach ($builds as $build) {
         $item = new PHUIStatusItemView();
         $item->setTarget($build_handles[$build->getPHID()]->renderLink());
         $status = $build->getBuildStatus();
         $status_name = HarbormasterBuild::getBuildStatusName($status);
         $icon = HarbormasterBuild::getBuildStatusIcon($status);
         $color = HarbormasterBuild::getBuildStatusColor($status);
         $item->setIcon($icon, $color, $status_name);
         $status_view->addItem($item);
     }
     $view = $ui_event->getValue('view');
     $view->addProperty(pht('Build Status'), $status_view);
 }
 private function handlePropertyEvent($ui_event)
 {
     $user = $ui_event->getUser();
     $object = $ui_event->getValue('object');
     if (!$object || !$object->getPHID()) {
         // No object, or the object has no PHID yet..
         return;
     }
     if (!$object instanceof PhrequentTrackableInterface) {
         // This object isn't a time trackable object.
         return;
     }
     if (!$this->canUseApplication($ui_event->getUser())) {
         return;
     }
     $events = id(new PhrequentUserTimeQuery())->setViewer($user)->withObjectPHIDs(array($object->getPHID()))->needPreemptingEvents(true)->execute();
     $event_groups = mgroup($events, 'getUserPHID');
     if (!$events) {
         return;
     }
     $handles = id(new PhabricatorHandleQuery())->setViewer($user)->withPHIDs(array_keys($event_groups))->execute();
     $status_view = new PHUIStatusListView();
     foreach ($event_groups as $user_phid => $event_group) {
         $item = new PHUIStatusItemView();
         $item->setTarget($handles[$user_phid]->renderLink());
         $state = 'stopped';
         foreach ($event_group as $event) {
             if ($event->getDateEnded() === null) {
                 if ($event->isPreempted()) {
                     $state = 'suspended';
                 } else {
                     $state = 'active';
                     break;
                 }
             }
         }
         switch ($state) {
             case 'active':
                 $item->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green', pht('Working Now'));
                 break;
             case 'suspended':
                 $item->setIcon(PHUIStatusItemView::ICON_CLOCK, 'yellow', pht('Interrupted'));
                 break;
             case 'stopped':
                 $item->setIcon(PHUIStatusItemView::ICON_CLOCK, 'bluegrey', pht('Not Working Now'));
                 break;
         }
         $block = new PhrequentTimeBlock($event_group);
         $item->setNote(phutil_format_relative_time($block->getTimeSpentOnObject($object->getPHID(), time())));
         $status_view->addItem($item);
     }
     $view = $ui_event->getValue('view');
     $view->addProperty(pht('Time Spent'), $status_view);
 }
 private function handlePropertyEvent($ui_event)
 {
     $user = $ui_event->getUser();
     $object = $ui_event->getValue('object');
     if (!$object || !$object->getPHID()) {
         // No object, or the object has no PHID yet..
         return;
     }
     if ($object instanceof HarbormasterBuildable) {
         // Although HarbormasterBuildable implements the correct interface, it
         // does not make sense to show a build's build status. In the best case
         // it is meaningless, and in the worst case it's confusing.
         return;
     }
     if (!$object instanceof HarbormasterBuildableInterface) {
         return;
     }
     $buildable_phid = $object->getHarbormasterBuildablePHID();
     if (!$buildable_phid) {
         return;
     }
     if (!$this->canUseApplication($ui_event->getUser())) {
         return;
     }
     $buildables = id(new HarbormasterBuildableQuery())->setViewer($user)->withManualBuildables(false)->withBuildablePHIDs(array($buildable_phid))->execute();
     if (!$buildables) {
         return;
     }
     $builds = id(new HarbormasterBuildQuery())->setViewer($user)->withBuildablePHIDs(mpull($buildables, 'getPHID'))->execute();
     if (!$builds) {
         return;
     }
     $build_handles = id(new PhabricatorHandleQuery())->setViewer($user)->withPHIDs(mpull($builds, 'getPHID'))->execute();
     $status_view = new PHUIStatusListView();
     foreach ($builds as $build) {
         $item = new PHUIStatusItemView();
         $item->setTarget($build_handles[$build->getPHID()]->renderLink());
         $status = $build->getBuildStatus();
         $status_name = HarbormasterBuild::getBuildStatusName($status);
         $icon = HarbormasterBuild::getBuildStatusIcon($status);
         $color = HarbormasterBuild::getBuildStatusColor($status);
         $item->setIcon($icon, $color, $status_name);
         $status_view->addItem($item);
     }
     $view = $ui_event->getValue('view');
     $view->addProperty(pht('Build Status'), $status_view);
 }
 public function buildCurtainPanel($object)
 {
     $viewer = $this->getViewer();
     $events = id(new PhrequentUserTimeQuery())->setViewer($viewer)->withObjectPHIDs(array($object->getPHID()))->needPreemptingEvents(true)->execute();
     $event_groups = mgroup($events, 'getUserPHID');
     if (!$events) {
         return;
     }
     $handles = $viewer->loadHandles(array_keys($event_groups));
     $status_view = new PHUIStatusListView();
     foreach ($event_groups as $user_phid => $event_group) {
         $item = new PHUIStatusItemView();
         $item->setTarget($handles[$user_phid]->renderLink());
         $state = 'stopped';
         foreach ($event_group as $event) {
             if ($event->getDateEnded() === null) {
                 if ($event->isPreempted()) {
                     $state = 'suspended';
                 } else {
                     $state = 'active';
                     break;
                 }
             }
         }
         switch ($state) {
             case 'active':
                 $item->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green', pht('Working Now'));
                 break;
             case 'suspended':
                 $item->setIcon(PHUIStatusItemView::ICON_CLOCK, 'yellow', pht('Interrupted'));
                 break;
             case 'stopped':
                 $item->setIcon(PHUIStatusItemView::ICON_CLOCK, 'bluegrey', pht('Not Working Now'));
                 break;
         }
         $block = new PhrequentTimeBlock($event_group);
         $item->setNote(phutil_format_relative_time($block->getTimeSpentOnObject($object->getPHID(), time())));
         $status_view->addItem($item);
     }
     return $this->newPanel()->setHeaderText(pht('Time Spent'))->setOrder(40000)->appendChild($status_view);
 }
 private function renderAuditStatusView(array $audit_requests)
 {
     assert_instances_of($audit_requests, 'PhabricatorRepositoryAuditRequest');
     $viewer = $this->getViewer();
     $authority_map = array_fill_keys($this->auditAuthorityPHIDs, true);
     $view = new PHUIStatusListView();
     foreach ($audit_requests as $request) {
         $code = $request->getAuditStatus();
         $item = new PHUIStatusItemView();
         $item->setIcon(PhabricatorAuditStatusConstants::getStatusIcon($code), PhabricatorAuditStatusConstants::getStatusColor($code), PhabricatorAuditStatusConstants::getStatusName($code));
         $note = array();
         foreach ($request->getAuditReasons() as $reason) {
             $note[] = phutil_tag('div', array(), $reason);
         }
         $item->setNote($note);
         $auditor_phid = $request->getAuditorPHID();
         $target = $viewer->renderHandle($auditor_phid);
         $item->setTarget($target);
         if (isset($authority_map[$auditor_phid])) {
             $item->setHighlighted(true);
         }
         $view->addItem($item);
     }
     return $view;
 }
 private function buildPropertyView(PhabricatorCalendarEvent $event)
 {
     $viewer = $this->getRequest()->getUser();
     $properties = id(new PHUIPropertyListView())->setUser($viewer)->setObject($event);
     if ($event->getIsAllDay()) {
         $date_start = phabricator_date($event->getDateFrom(), $viewer);
         $date_end = phabricator_date($event->getDateTo(), $viewer);
         if ($date_start == $date_end) {
             $properties->addProperty(pht('Time'), phabricator_date($event->getDateFrom(), $viewer));
         } else {
             $properties->addProperty(pht('Starts'), phabricator_date($event->getDateFrom(), $viewer));
             $properties->addProperty(pht('Ends'), phabricator_date($event->getDateTo(), $viewer));
         }
     } else {
         $properties->addProperty(pht('Starts'), phabricator_datetime($event->getDateFrom(), $viewer));
         $properties->addProperty(pht('Ends'), phabricator_datetime($event->getDateTo(), $viewer));
     }
     if ($event->getIsRecurring()) {
         $properties->addProperty(pht('Recurs'), ucwords(idx($event->getRecurrenceFrequency(), 'rule')));
         if ($event->getRecurrenceEndDate()) {
             $properties->addProperty(pht('Recurrence Ends'), phabricator_datetime($event->getRecurrenceEndDate(), $viewer));
         }
         if ($event->getInstanceOfEventPHID()) {
             $properties->addProperty(pht('Recurrence of Event'), pht('%s of %s', $event->getSequenceIndex(), $viewer->renderHandle($event->getInstanceOfEventPHID())->render()));
         }
     }
     $properties->addProperty(pht('Host'), $viewer->renderHandle($event->getUserPHID()));
     $invitees = $event->getInvitees();
     foreach ($invitees as $key => $invitee) {
         if ($invitee->isUninvited()) {
             unset($invitees[$key]);
         }
     }
     if ($invitees) {
         $invitee_list = new PHUIStatusListView();
         $icon_invited = PHUIStatusItemView::ICON_OPEN;
         $icon_attending = PHUIStatusItemView::ICON_ACCEPT;
         $icon_declined = PHUIStatusItemView::ICON_REJECT;
         $status_invited = PhabricatorCalendarEventInvitee::STATUS_INVITED;
         $status_attending = PhabricatorCalendarEventInvitee::STATUS_ATTENDING;
         $status_declined = PhabricatorCalendarEventInvitee::STATUS_DECLINED;
         $icon_map = array($status_invited => $icon_invited, $status_attending => $icon_attending, $status_declined => $icon_declined);
         $icon_color_map = array($status_invited => null, $status_attending => 'green', $status_declined => 'red');
         foreach ($invitees as $invitee) {
             $item = new PHUIStatusItemView();
             $invitee_phid = $invitee->getInviteePHID();
             $status = $invitee->getStatus();
             $target = $viewer->renderHandle($invitee_phid);
             $icon = $icon_map[$status];
             $icon_color = $icon_color_map[$status];
             $item->setIcon($icon, $icon_color)->setTarget($target);
             $invitee_list->addItem($item);
         }
     } else {
         $invitee_list = phutil_tag('em', array(), pht('None'));
     }
     $properties->addProperty(pht('Invitees'), $invitee_list);
     $properties->invokeWillRenderEvent();
     $properties->addProperty(pht('Icon'), id(new PhabricatorCalendarIconSet())->getIconLabel($event->getIcon()));
     if (strlen($event->getDescription())) {
         $description = PhabricatorMarkupEngine::renderOneObject(id(new PhabricatorMarkupOneOff())->setContent($event->getDescription()), 'default', $viewer);
         $properties->addSectionHeader(pht('Description'), PHUIPropertyListView::ICON_SUMMARY);
         $properties->addTextContent($description);
     }
     return $properties;
 }
 public function render()
 {
     $viewer = $this->getUser();
     $view = new PHUIStatusListView();
     foreach ($this->reviewers as $reviewer) {
         $phid = $reviewer->getReviewerPHID();
         $handle = $this->handles[$phid];
         // If we're missing either the diff or action information for the
         // reviewer, render information as current.
         $is_current = !$this->diff || !$reviewer->getDiffID() || $this->diff->getID() == $reviewer->getDiffID();
         $item = new PHUIStatusItemView();
         $item->setHighlighted($reviewer->hasAuthority($viewer));
         switch ($reviewer->getStatus()) {
             case DifferentialReviewerStatus::STATUS_ADDED:
                 $item->setIcon(PHUIStatusItemView::ICON_OPEN, 'bluegrey', pht('Review Requested'));
                 break;
             case DifferentialReviewerStatus::STATUS_ACCEPTED:
                 if ($is_current) {
                     $item->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green', pht('Accepted'));
                 } else {
                     $item->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'dark', pht('Accepted Prior Diff'));
                 }
                 break;
             case DifferentialReviewerStatus::STATUS_ACCEPTED_OLDER:
                 $item->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'dark', pht('Accepted Prior Diff'));
                 break;
             case DifferentialReviewerStatus::STATUS_REJECTED:
                 if ($is_current) {
                     $item->setIcon(PHUIStatusItemView::ICON_REJECT, 'red', pht('Requested Changes'));
                 } else {
                     $item->setIcon(PHUIStatusItemView::ICON_REJECT, 'dark', pht('Requested Changes to Prior Diff'));
                 }
                 break;
             case DifferentialReviewerStatus::STATUS_REJECTED_OLDER:
                 $item->setIcon(PHUIStatusItemView::ICON_REJECT, 'dark', pht('Rejected Prior Diff'));
                 break;
             case DifferentialReviewerStatus::STATUS_COMMENTED:
                 if ($is_current) {
                     $item->setIcon(PHUIStatusItemView::ICON_INFO, 'blue', pht('Commented'));
                 } else {
                     $item->setIcon('info-dark', pht('Commented Previously'));
                 }
                 break;
             case DifferentialReviewerStatus::STATUS_BLOCKING:
                 $item->setIcon(PHUIStatusItemView::ICON_MINUS, 'red', pht('Blocking Review'));
                 break;
             default:
                 $item->setIcon(PHUIStatusItemView::ICON_QUESTION, 'bluegrey', pht('%s?', $reviewer->getStatus()));
                 break;
         }
         $item->setTarget($handle->renderHovercardLink());
         $view->addItem($item);
     }
     return $view;
 }
 private function renderAuditStatusView(array $audit_requests)
 {
     assert_instances_of($audit_requests, 'PhabricatorRepositoryAuditRequest');
     $phids = mpull($audit_requests, 'getAuditorPHID');
     $this->loadHandles($phids);
     $authority_map = array_fill_keys($this->auditAuthorityPHIDs, true);
     $view = new PHUIStatusListView();
     foreach ($audit_requests as $request) {
         $item = new PHUIStatusItemView();
         switch ($request->getAuditStatus()) {
             case PhabricatorAuditStatusConstants::AUDIT_NOT_REQUIRED:
                 $item->setIcon(PHUIStatusItemView::ICON_OPEN, 'blue', pht('Commented'));
                 break;
             case PhabricatorAuditStatusConstants::AUDIT_REQUIRED:
                 $item->setIcon(PHUIStatusItemView::ICON_WARNING, 'blue', pht('Audit Required'));
                 break;
             case PhabricatorAuditStatusConstants::CONCERNED:
                 $item->setIcon(PHUIStatusItemView::ICON_REJECT, 'red', pht('Concern Raised'));
                 break;
             case PhabricatorAuditStatusConstants::ACCEPTED:
                 $item->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green', pht('Accepted'));
                 break;
             case PhabricatorAuditStatusConstants::AUDIT_REQUESTED:
                 $item->setIcon(PHUIStatusItemView::ICON_WARNING, 'dark', pht('Audit Requested'));
                 break;
             case PhabricatorAuditStatusConstants::RESIGNED:
                 $item->setIcon(PHUIStatusItemView::ICON_OPEN, 'dark', pht('Resigned'));
                 break;
             case PhabricatorAuditStatusConstants::CLOSED:
                 $item->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'blue', pht('Closed'));
                 break;
             default:
                 $item->setIcon(PHUIStatusItemView::ICON_QUESTION, 'dark', pht('%s?', $request->getAuditStatus()));
                 break;
         }
         $note = array();
         foreach ($request->getAuditReasons() as $reason) {
             $note[] = phutil_tag('div', array(), $reason);
         }
         $item->setNote($note);
         $auditor_phid = $request->getAuditorPHID();
         $target = $this->getHandle($auditor_phid)->renderLink();
         $item->setTarget($target);
         if (isset($authority_map[$auditor_phid])) {
             $item->setHighlighted(true);
         }
         $view->addItem($item);
     }
     return $view;
 }
 private function getStatus(HarbormasterBuild $build)
 {
     $status_view = new PHUIStatusListView();
     $item = new PHUIStatusItemView();
     if ($build->isStopping()) {
         $status_name = pht('Pausing');
         $icon = PHUIStatusItemView::ICON_RIGHT;
         $color = 'dark';
     } else {
         $status = $build->getBuildStatus();
         $status_name = HarbormasterBuild::getBuildStatusName($status);
         $icon = HarbormasterBuild::getBuildStatusIcon($status);
         $color = HarbormasterBuild::getBuildStatusColor($status);
     }
     $item->setTarget($status_name);
     $item->setIcon($icon, $color);
     $status_view->addItem($item);
     return $status_view;
 }
 private function buildPropertySection(PhabricatorCalendarEvent $event)
 {
     $viewer = $this->getViewer();
     $properties = id(new PHUIPropertyListView())->setUser($viewer);
     $invitees = $event->getInvitees();
     foreach ($invitees as $key => $invitee) {
         if ($invitee->isUninvited()) {
             unset($invitees[$key]);
         }
     }
     if ($invitees) {
         $invitee_list = new PHUIStatusListView();
         $icon_invited = PHUIStatusItemView::ICON_OPEN;
         $icon_attending = PHUIStatusItemView::ICON_ACCEPT;
         $icon_declined = PHUIStatusItemView::ICON_REJECT;
         $status_invited = PhabricatorCalendarEventInvitee::STATUS_INVITED;
         $status_attending = PhabricatorCalendarEventInvitee::STATUS_ATTENDING;
         $status_declined = PhabricatorCalendarEventInvitee::STATUS_DECLINED;
         $icon_map = array($status_invited => $icon_invited, $status_attending => $icon_attending, $status_declined => $icon_declined);
         $icon_color_map = array($status_invited => null, $status_attending => 'green', $status_declined => 'red');
         foreach ($invitees as $invitee) {
             $item = new PHUIStatusItemView();
             $invitee_phid = $invitee->getInviteePHID();
             $status = $invitee->getStatus();
             $target = $viewer->renderHandle($invitee_phid);
             $icon = $icon_map[$status];
             $icon_color = $icon_color_map[$status];
             $item->setIcon($icon, $icon_color)->setTarget($target);
             $invitee_list->addItem($item);
         }
     } else {
         $invitee_list = phutil_tag('em', array(), pht('None'));
     }
     $properties->addProperty(pht('Invitees'), $invitee_list);
     $properties->invokeWillRenderEvent();
     return $properties;
 }
 private function buildPropertySection(PhabricatorCalendarEvent $event)
 {
     $viewer = $this->getViewer();
     $properties = id(new PHUIPropertyListView())->setUser($viewer);
     $invitees = $event->getInvitees();
     foreach ($invitees as $key => $invitee) {
         if ($invitee->isUninvited()) {
             unset($invitees[$key]);
         }
     }
     if ($invitees) {
         $invitee_list = new PHUIStatusListView();
         $icon_invited = PHUIStatusItemView::ICON_OPEN;
         $icon_attending = PHUIStatusItemView::ICON_ACCEPT;
         $icon_declined = PHUIStatusItemView::ICON_REJECT;
         $status_invited = PhabricatorCalendarEventInvitee::STATUS_INVITED;
         $status_attending = PhabricatorCalendarEventInvitee::STATUS_ATTENDING;
         $status_declined = PhabricatorCalendarEventInvitee::STATUS_DECLINED;
         $icon_map = array($status_invited => $icon_invited, $status_attending => $icon_attending, $status_declined => $icon_declined);
         $icon_color_map = array($status_invited => null, $status_attending => 'green', $status_declined => 'red');
         $viewer_phid = $viewer->getPHID();
         $is_rsvp_invited = $event->isRSVPInvited($viewer_phid);
         $type_user = PhabricatorPeopleUserPHIDType::TYPECONST;
         $head = array();
         $tail = array();
         foreach ($invitees as $invitee) {
             $item = new PHUIStatusItemView();
             $invitee_phid = $invitee->getInviteePHID();
             $status = $invitee->getStatus();
             $target = $viewer->renderHandle($invitee_phid);
             $is_user = phid_get_type($invitee_phid) == $type_user;
             if (!$is_user) {
                 $icon = 'fa-users';
                 $icon_color = 'blue';
             } else {
                 $icon = $icon_map[$status];
                 $icon_color = $icon_color_map[$status];
             }
             // Highlight invited groups which you're a member of if you have
             // not RSVP'd to an event yet.
             if ($is_rsvp_invited) {
                 if ($invitee_phid != $viewer_phid) {
                     if ($event->hasRSVPAuthority($viewer_phid, $invitee_phid)) {
                         $item->setHighlighted(true);
                     }
                 }
             }
             $item->setIcon($icon, $icon_color)->setTarget($target);
             if ($is_user) {
                 $tail[] = $item;
             } else {
                 $head[] = $item;
             }
         }
         foreach (array_merge($head, $tail) as $item) {
             $invitee_list->addItem($item);
         }
     } else {
         $invitee_list = phutil_tag('em', array(), pht('None'));
     }
     if ($event->isImportedEvent()) {
         $properties->addProperty(pht('Imported By'), pht('%s from %s', $viewer->renderHandle($event->getImportAuthorPHID()), $viewer->renderHandle($event->getImportSourcePHID())));
     }
     $properties->addProperty(pht('Invitees'), $invitee_list);
     $properties->invokeWillRenderEvent();
     return $properties;
 }