public function handleRequest(AphrontRequest $request) { $viewer = $this->getViewer(); $configs = id(new PhabricatorAuthProviderConfigQuery())->setViewer($viewer)->execute(); $list = new PHUIObjectItemListView(); $can_manage = $this->hasApplicationCapability(AuthManageProvidersCapability::CAPABILITY); foreach ($configs as $config) { $item = new PHUIObjectItemView(); $id = $config->getID(); $edit_uri = $this->getApplicationURI('config/edit/' . $id . '/'); $enable_uri = $this->getApplicationURI('config/enable/' . $id . '/'); $disable_uri = $this->getApplicationURI('config/disable/' . $id . '/'); $provider = $config->getProvider(); if ($provider) { $name = $provider->getProviderName(); } else { $name = $config->getProviderType() . ' (' . $config->getProviderClass() . ')'; } $item->setHeader($name); if ($provider) { $item->setHref($edit_uri); } else { $item->addAttribute(pht('Provider Implementation Missing!')); } $domain = null; if ($provider) { $domain = $provider->getProviderDomain(); if ($domain !== 'self') { $item->addAttribute($domain); } } if ($config->getShouldAllowRegistration()) { $item->addAttribute(pht('Allows Registration')); } else { $item->addAttribute(pht('Does Not Allow Registration')); } if ($config->getIsEnabled()) { $item->setStatusIcon('fa-check-circle green'); $item->addAction(id(new PHUIListItemView())->setIcon('fa-times')->setHref($disable_uri)->setDisabled(!$can_manage)->addSigil('workflow')); } else { $item->setStatusIcon('fa-ban red'); $item->addIcon('fa-ban grey', pht('Disabled')); $item->addAction(id(new PHUIListItemView())->setIcon('fa-plus')->setHref($enable_uri)->setDisabled(!$can_manage)->addSigil('workflow')); } $list->addItem($item); } $list->setNoDataString(pht('%s You have not added authentication providers yet. Use "%s" to add ' . 'a provider, which will let users register new Phabricator accounts ' . 'and log in.', phutil_tag('strong', array(), pht('No Providers Configured:')), phutil_tag('a', array('href' => $this->getApplicationURI('config/new/')), pht('Add Authentication Provider')))); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Auth Providers')); $crumbs->setBorder(true); $guidance_context = new PhabricatorAuthProvidersGuidanceContext(); $guidance = id(new PhabricatorGuidanceEngine())->setViewer($viewer)->setGuidanceContext($guidance_context)->newInfoView(); $button = id(new PHUIButtonView())->setTag('a')->setColor(PHUIButtonView::SIMPLE)->setHref($this->getApplicationURI('config/new/'))->setIcon('fa-plus')->setDisabled(!$can_manage)->setText(pht('Add Provider')); $list->setFlush(true); $list = id(new PHUIObjectBoxView())->setHeaderText(pht('Providers'))->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)->appendChild($list); $title = pht('Auth Providers'); $header = id(new PHUIHeaderView())->setHeader($title)->setHeaderIcon('fa-key')->addActionLink($button); $view = id(new PHUITwoColumnView())->setHeader($header)->setFooter(array($guidance, $list)); return $this->newPage()->setTitle($title)->setCrumbs($crumbs)->appendChild($view); }
private function buildPaymentMethodsSection(PhortuneAccount $account) { $request = $this->getRequest(); $viewer = $request->getUser(); $can_edit = PhabricatorPolicyFilter::hasCapability($viewer, $account, PhabricatorPolicyCapability::CAN_EDIT); $id = $account->getID(); $header = id(new PHUIHeaderView())->setHeader(pht('Payment Methods'))->addActionLink(id(new PHUIButtonView())->setTag('a')->setHref($this->getApplicationURI($id . '/card/new/'))->setText(pht('Add Payment Method'))->setIcon(id(new PHUIIconView())->setIconFont('fa-plus'))); $list = id(new PHUIObjectItemListView())->setUser($viewer)->setNoDataString(pht('No payment methods associated with this account.')); $methods = id(new PhortunePaymentMethodQuery())->setViewer($viewer)->withAccountPHIDs(array($account->getPHID()))->execute(); if ($methods) { $this->loadHandles(mpull($methods, 'getAuthorPHID')); } foreach ($methods as $method) { $id = $method->getID(); $item = new PHUIObjectItemView(); $item->setHeader($method->getFullDisplayName()); switch ($method->getStatus()) { case PhortunePaymentMethod::STATUS_ACTIVE: $item->setBarColor('green'); $disable_uri = $this->getApplicationURI('card/' . $id . '/disable/'); $item->addAction(id(new PHUIListItemView())->setIcon('fa-times')->setHref($disable_uri)->setDisabled(!$can_edit)->setWorkflow(true)); break; case PhortunePaymentMethod::STATUS_DISABLED: $item->setDisabled(true); break; } $provider = $method->buildPaymentProvider(); $item->addAttribute($provider->getPaymentMethodProviderDescription()); $item->setImageURI($provider->getPaymentMethodIcon()); $edit_uri = $this->getApplicationURI('card/' . $id . '/edit/'); $item->addAction(id(new PHUIListItemView())->setIcon('fa-pencil')->setHref($edit_uri)->setDisabled(!$can_edit)->setWorkflow(!$can_edit)); $list->addItem($item); } return id(new PHUIObjectBoxView())->setHeader($header)->appendChild($list); }
private function buildPaymentMethodsSection(PhortuneAccount $account) { $request = $this->getRequest(); $viewer = $request->getUser(); $can_edit = PhabricatorPolicyFilter::hasCapability($viewer, $account, PhabricatorPolicyCapability::CAN_EDIT); $id = $account->getID(); $header = id(new PHUIHeaderView())->setHeader(pht('Payment Methods')); $list = id(new PHUIObjectItemListView())->setUser($viewer)->setFlush(true)->setNoDataString(pht('No payment methods associated with this account.')); $methods = id(new PhortunePaymentMethodQuery())->setViewer($viewer)->withAccountPHIDs(array($account->getPHID()))->execute(); foreach ($methods as $method) { $id = $method->getID(); $item = new PHUIObjectItemView(); $item->setHeader($method->getFullDisplayName()); switch ($method->getStatus()) { case PhortunePaymentMethod::STATUS_ACTIVE: $item->setStatusIcon('fa-check green'); $disable_uri = $this->getApplicationURI('card/' . $id . '/disable/'); $item->addAction(id(new PHUIListItemView())->setIcon('fa-times')->setHref($disable_uri)->setDisabled(!$can_edit)->setWorkflow(true)); break; case PhortunePaymentMethod::STATUS_DISABLED: $item->setStatusIcon('fa-ban lightbluetext'); $item->setDisabled(true); break; } $provider = $method->buildPaymentProvider(); $item->addAttribute($provider->getPaymentMethodProviderDescription()); $edit_uri = $this->getApplicationURI('card/' . $id . '/edit/'); $item->addAction(id(new PHUIListItemView())->setIcon('fa-pencil')->setHref($edit_uri)->setDisabled(!$can_edit)->setWorkflow(!$can_edit)); $list->addItem($item); } return id(new PHUIObjectBoxView())->setHeader($header)->setObjectList($list); }
protected function renderResultList(array $transcripts, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($transcripts, 'HeraldTranscript'); $viewer = $this->requireViewer(); $list = new PHUIObjectItemListView(); foreach ($transcripts as $xscript) { $view_href = phutil_tag('a', array('href' => '/herald/transcript/' . $xscript->getID() . '/'), pht('View Full Transcript')); $item = new PHUIObjectItemView(); $item->setObjectName($xscript->getID()); $item->setHeader($view_href); if ($xscript->getDryRun()) { $item->addAttribute(pht('Dry Run')); } $item->addAttribute($handles[$xscript->getObjectPHID()]->renderLink()); $item->addAttribute(pht('%s ms', new PhutilNumber((int) (1000 * $xscript->getDuration())))); $item->addIcon('none', phabricator_datetime($xscript->getTime(), $viewer)); $list->addItem($item); } return $list; }
protected function renderResultList(array $lists, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($lists, 'PhabricatorMetaMTAMailingList'); $view = id(new PHUIObjectItemListView()); foreach ($lists as $list) { $item = new PHUIObjectItemView(); $item->setHeader($list->getName()); $item->setHref($list->getURI()); $item->addAttribute($list->getEmail()); $item->addAction(id(new PHUIListItemView())->setIcon('fa-pencil')->setHref($this->getApplicationURI('/edit/' . $list->getID() . '/'))); $view->addItem($item); } return $view; }
public function render() { $handles = $this->handles; require_celerity_resource('maniphest-task-summary-css'); $list = new PHUIObjectItemListView(); $list->setFlush(true); $status_map = ManiphestTaskStatus::getTaskStatusMap(); $color_map = ManiphestTaskPriority::getColorMap(); if ($this->showBatchControls) { Javelin::initBehavior('maniphest-list-editor'); } foreach ($this->tasks as $task) { $item = new PHUIObjectItemView(); $item->setObjectName('T' . $task->getID()); $item->setHeader($task->getTitle()); $item->setHref('/T' . $task->getID()); if ($task->getOwnerPHID()) { $owner = $handles[$task->getOwnerPHID()]; $item->addByline(pht('Assigned: %s', $owner->renderLink())); } $status = $task->getStatus(); if ($task->isClosed()) { $item->setDisabled(true); } $item->setBarColor(idx($color_map, $task->getPriority(), 'grey')); $item->addIcon('none', phabricator_datetime($task->getDateModified(), $this->getUser())); if ($this->showSubpriorityControls) { $item->setGrippable(true); } if ($this->showSubpriorityControls || $this->showBatchControls) { $item->addSigil('maniphest-task'); } $project_handles = array_select_keys($handles, $task->getProjectPHIDs()); $item->addAttribute(id(new PHUIHandleTagListView())->setLimit(4)->setNoDataString(pht('No Projects'))->setSlim(true)->setHandles($project_handles)); $item->setMetadata(array('taskID' => $task->getID())); if ($this->showBatchControls) { $href = new PhutilURI('/maniphest/task/edit/' . $task->getID() . '/'); if (!$this->showSubpriorityControls) { $href->setQueryParam('ungrippable', 'true'); } $item->addAction(id(new PHUIListItemView())->setIcon('fa-pencil')->addSigil('maniphest-edit-task')->setHref($href)); } $list->addItem($item); } return $list; }
public function willRenderLinkedAccount(PhabricatorUser $viewer, PHUIObjectItemView $item, PhabricatorExternalAccount $account) { // Get a valid token, possibly refreshing it. If we're unable to refresh // it, render a message to that effect. The user may be able to repair the // link by manually reconnecting. $is_invalid = false; try { $oauth_token = $this->getOAuthAccessToken($account); } catch (Exception $ex) { $oauth_token = null; $is_invalid = true; } $item->addAttribute(pht('OAuth2 Account')); if ($oauth_token) { $oauth_expires = $account->getProperty('oauth.token.access.expires'); if ($oauth_expires) { $item->addAttribute(pht('Active OAuth Token (Expires: %s)', phabricator_datetime($oauth_expires, $viewer))); } else { $item->addAttribute(pht('Active OAuth Token')); } } else { if ($is_invalid) { $item->addAttribute(pht('Invalid OAuth Access Token')); } else { $item->addAttribute(pht('No OAuth Access Token')); } } parent::willRenderLinkedAccount($viewer, $item, $account); }
protected function renderResultList(array $questions, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($questions, 'PonderQuestion'); $viewer = $this->requireViewer(); $proj_phids = array(); foreach ($questions as $question) { foreach ($question->getProjectPHIDs() as $project_phid) { $proj_phids[] = $project_phid; } } $proj_handles = id(new PhabricatorHandleQuery())->setViewer($viewer)->withPHIDs($proj_phids)->execute(); $view = id(new PHUIObjectItemListView())->setUser($viewer); foreach ($questions as $question) { $color = PonderQuestionStatus::getQuestionStatusTagColor($question->getStatus()); $icon = PonderQuestionStatus::getQuestionStatusIcon($question->getStatus()); $full_status = PonderQuestionStatus::getQuestionStatusFullName($question->getStatus()); $item = new PHUIObjectItemView(); $item->setObjectName('Q' . $question->getID()); $item->setHeader($question->getTitle()); $item->setHref('/Q' . $question->getID()); $item->setObject($question); $item->setStatusIcon($icon . ' ' . $color, $full_status); $project_handles = array_select_keys($proj_handles, $question->getProjectPHIDs()); $created_date = phabricator_date($question->getDateCreated(), $viewer); $item->addIcon('none', $created_date); $item->addByline(pht('Asked by %s', $handles[$question->getAuthorPHID()]->renderLink())); $item->addAttribute(pht('%d Answer(s)', $question->getAnswerCount())); if ($project_handles) { $item->addAttribute(id(new PHUIHandleTagListView())->setLimit(4)->setSlim(true)->setHandles($project_handles)); } $view->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($view); $result->setNoDataString(pht('No questions found.')); return $result; }
protected function renderResultList(array $users, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($users, 'PhabricatorUser'); $request = $this->getRequest(); $viewer = $this->requireViewer(); $list = new PHUIObjectItemListView(); $is_approval = $query->getQueryKey() == 'approval'; foreach ($users as $user) { $primary_email = $user->loadPrimaryEmail(); if ($primary_email && $primary_email->getIsVerified()) { $email = pht('Verified'); } else { $email = pht('Unverified'); } $item = new PHUIObjectItemView(); $item->setHeader($user->getFullName())->setHref('/p/' . $user->getUsername() . '/')->addAttribute(phabricator_datetime($user->getDateCreated(), $viewer))->addAttribute($email)->setImageURI($user->getProfileImageURI()); if ($is_approval && $primary_email) { $item->addAttribute($primary_email->getAddress()); } if ($user->getIsDisabled()) { $item->addIcon('fa-ban', pht('Disabled')); } if (!$is_approval) { if (!$user->getIsApproved()) { $item->addIcon('fa-clock-o', pht('Needs Approval')); } } if ($user->getIsAdmin()) { $item->addIcon('fa-star', pht('Admin')); } if ($user->getIsSystemAgent()) { $item->addIcon('fa-desktop', pht('Bot/Script')); } if ($viewer->getIsAdmin()) { $user_id = $user->getID(); if ($is_approval) { $item->addAction(id(new PHUIListItemView())->setIcon('fa-ban')->setName(pht('Disable'))->setWorkflow(true)->setHref($this->getApplicationURI('disapprove/' . $user_id . '/'))); $item->addAction(id(new PHUIListItemView())->setIcon('fa-thumbs-o-up')->setName(pht('Approve'))->setWorkflow(true)->setHref($this->getApplicationURI('approve/' . $user_id . '/'))); } } $list->addItem($item); } return $list; }
public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $configs = id(new PhabricatorAuthProviderConfigQuery())->setViewer($viewer)->execute(); $list = new PHUIObjectItemListView(); $can_manage = $this->hasApplicationCapability(AuthManageProvidersCapability::CAPABILITY); foreach ($configs as $config) { $item = new PHUIObjectItemView(); $id = $config->getID(); $edit_uri = $this->getApplicationURI('config/edit/' . $id . '/'); $enable_uri = $this->getApplicationURI('config/enable/' . $id . '/'); $disable_uri = $this->getApplicationURI('config/disable/' . $id . '/'); $provider = $config->getProvider(); if ($provider) { $name = $provider->getProviderName(); } else { $name = $config->getProviderType() . ' (' . $config->getProviderClass() . ')'; } $item->setHeader($name); if ($provider) { $item->setHref($edit_uri); } else { $item->addAttribute(pht('Provider Implementation Missing!')); } $domain = null; if ($provider) { $domain = $provider->getProviderDomain(); if ($domain !== 'self') { $item->addAttribute($domain); } } if ($config->getShouldAllowRegistration()) { $item->addAttribute(pht('Allows Registration')); } else { $item->addAttribute(pht('Does Not Allow Registration')); } if ($config->getIsEnabled()) { $item->setState(PHUIObjectItemView::STATE_SUCCESS); $item->addAction(id(new PHUIListItemView())->setIcon('fa-times')->setHref($disable_uri)->setDisabled(!$can_manage)->addSigil('workflow')); } else { $item->setState(PHUIObjectItemView::STATE_FAIL); $item->addIcon('fa-times grey', pht('Disabled')); $item->addAction(id(new PHUIListItemView())->setIcon('fa-plus')->setHref($enable_uri)->setDisabled(!$can_manage)->addSigil('workflow')); } $list->addItem($item); } $list->setNoDataString(pht('%s You have not added authentication providers yet. Use "%s" to add ' . 'a provider, which will let users register new Phabricator accounts ' . 'and log in.', phutil_tag('strong', array(), pht('No Providers Configured:')), phutil_tag('a', array('href' => $this->getApplicationURI('config/new/')), pht('Add Authentication Provider')))); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Auth Providers')); $domains_key = 'auth.email-domains'; $domains_link = $this->renderConfigLink($domains_key); $domains_value = PhabricatorEnv::getEnvConfig($domains_key); $approval_key = 'auth.require-approval'; $approval_link = $this->renderConfigLink($approval_key); $approval_value = PhabricatorEnv::getEnvConfig($approval_key); $issues = array(); if ($domains_value) { $issues[] = pht('Phabricator is configured with an email domain whitelist (in %s), so ' . 'only users with a verified email address at one of these %s ' . 'allowed domain(s) will be able to register an account: %s', $domains_link, phutil_count($domains_value), phutil_tag('strong', array(), implode(', ', $domains_value))); } else { $issues[] = pht('Anyone who can browse to this Phabricator install will be able to ' . 'register an account. To add email domain restrictions, configure ' . '%s.', $domains_link); } if ($approval_value) { $issues[] = pht('Administrative approvals are enabled (in %s), so all new users must ' . 'have their accounts approved by an administrator.', $approval_link); } else { $issues[] = pht('Administrative approvals are disabled, so users who register will ' . 'be able to use their accounts immediately. To enable approvals, ' . 'configure %s.', $approval_link); } if (!$domains_value && !$approval_value) { $severity = PHUIInfoView::SEVERITY_WARNING; $issues[] = pht('You can safely ignore this warning if the install itself has ' . 'access controls (for example, it is deployed on a VPN) or if all of ' . 'the configured providers have access controls (for example, they are ' . 'all private LDAP or OAuth servers).'); } else { $severity = PHUIInfoView::SEVERITY_NOTICE; } $warning = id(new PHUIInfoView())->setSeverity($severity)->setErrors($issues); $image = id(new PHUIIconView())->setIconFont('fa-plus'); $button = id(new PHUIButtonView())->setTag('a')->setColor(PHUIButtonView::SIMPLE)->setHref($this->getApplicationURI('config/new/'))->setIcon($image)->setDisabled(!$can_manage)->setText(pht('Add Provider')); $header = id(new PHUIHeaderView())->setHeader(pht('Authentication Providers'))->addActionLink($button); $list->setFlush(true); $list = id(new PHUIObjectBoxView())->setHeader($header)->setInfoView($warning)->appendChild($list); return $this->buildApplicationPage(array($crumbs, $list), array('title' => pht('Authentication Providers'))); }
private function buildApplyTranscriptPanel(HeraldTranscript $xscript) { $handles = $this->handles; $adapter = $this->getAdapter(); $rule_type_global = HeraldRuleTypeConfig::RULE_TYPE_GLOBAL; $action_names = $adapter->getActionNameMap($rule_type_global); $list = new PHUIObjectItemListView(); $list->setStates(true); $list->setNoDataString(pht('No actions were taken.')); foreach ($xscript->getApplyTranscripts() as $apply_xscript) { $target = $apply_xscript->getTarget(); switch ($apply_xscript->getAction()) { case HeraldAdapter::ACTION_NOTHING: $target = null; break; case HeraldAdapter::ACTION_FLAG: $target = PhabricatorFlagColor::getColorName($target); break; case HeraldAdapter::ACTION_BLOCK: // Target is a text string. $target = $target; break; default: if (is_array($target) && $target) { foreach ($target as $k => $phid) { if (isset($handles[$phid])) { $target[$k] = $handles[$phid]->getName(); } } $target = implode(', ', $target); } else { if (is_string($target)) { $target = $target; } else { $target = '<empty>'; } } break; } $item = new PHUIObjectItemView(); if ($apply_xscript->getApplied()) { $item->setState(PHUIObjectItemView::STATE_SUCCESS); } else { $item->setState(PHUIObjectItemView::STATE_FAIL); } $rule = idx($action_names, $apply_xscript->getAction(), pht('Unknown Action "%s"', $apply_xscript->getAction())); $item->setHeader(pht('%s: %s', $rule, $target)); $item->addAttribute($apply_xscript->getReason()); $item->addAttribute(pht('Outcome: %s', $apply_xscript->getAppliedReason())); $list->addItem($item); } $box = new PHUIObjectBoxView(); $box->setHeaderText(pht('Actions Taken')); $box->appendChild($list); return $box; }
private function buildSidebar(PonderQuestion $question) { $viewer = $this->getViewer(); $status = $question->getStatus(); $id = $question->getID(); $questions = id(new PonderQuestionQuery())->setViewer($viewer)->withStatuses(array($status))->withEdgeLogicPHIDs(PhabricatorProjectObjectHasProjectEdgeType::EDGECONST, PhabricatorQueryConstraint::OPERATOR_OR, $question->getProjectPHIDs())->setLimit(10)->execute(); $list = id(new PHUIObjectItemListView())->setUser($viewer)->setNoDataString(pht('No similar questions found.')); foreach ($questions as $question) { if ($id == $question->getID()) { continue; } $item = new PHUIObjectItemView(); $item->setObjectName('Q' . $question->getID()); $item->setHeader($question->getTitle()); $item->setHref('/Q' . $question->getID()); $item->setObject($question); $item->addAttribute(pht('%d Answer(s)', $question->getAnswerCount())); $list->addItem($item); } $box = id(new PHUIObjectBoxView())->setHeaderText(pht('Similar Questions'))->setObjectList($list); return $box; }
protected function renderResultList(array $questions, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($questions, 'PonderQuestion'); $viewer = $this->requireViewer(); $view = id(new PHUIObjectItemListView())->setUser($viewer); foreach ($questions as $question) { $item = new PHUIObjectItemView(); $item->setObjectName('Q' . $question->getID()); $item->setHeader($question->getTitle()); $item->setHref('/Q' . $question->getID()); $item->setObject($question); $item->setBarColor(PonderQuestionStatus::getQuestionStatusTagColor($question->getStatus())); $created_date = phabricator_date($question->getDateCreated(), $viewer); $item->addIcon('none', $created_date); $item->addByline(pht('Asked by %s', $handles[$question->getAuthorPHID()]->renderLink())); $item->addAttribute(pht('%d Answer(s)', $question->getAnswerCount())); $view->addItem($item); } return $view; }
public function willRenderLinkedAccount(PhabricatorUser $viewer, PHUIObjectItemView $item, PhabricatorExternalAccount $account) { $item->addAttribute(pht('OAuth1 Account')); parent::willRenderLinkedAccount($viewer, $item, $account); }
protected function renderResultList(array $usertimes, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($usertimes, 'PhrequentUserTime'); $viewer = $this->requireViewer(); $view = id(new PHUIObjectItemListView())->setUser($viewer); foreach ($usertimes as $usertime) { $item = new PHUIObjectItemView(); if ($usertime->getObjectPHID() === null) { $item->setHeader($usertime->getNote()); } else { $obj = $handles[$usertime->getObjectPHID()]; $item->setHeader($obj->getLinkName()); $item->setHref($obj->getURI()); } $item->setObject($usertime); $item->addByline(pht('Tracked: %s', $handles[$usertime->getUserPHID()]->renderLink())); $started_date = phabricator_date($usertime->getDateStarted(), $viewer); $item->addIcon('none', $started_date); $block = new PhrequentTimeBlock(array($usertime)); $time_spent = $block->getTimeSpentOnObject($usertime->getObjectPHID(), PhabricatorTime::getNow()); $time_spent = $time_spent == 0 ? 'none' : phutil_format_relative_time_detailed($time_spent); if ($usertime->getDateEnded() !== null) { $item->addAttribute(pht('Tracked %s', $time_spent)); $item->addAttribute(pht('Ended on %s', phabricator_datetime($usertime->getDateEnded(), $viewer))); } else { $item->addAttribute(pht('Tracked %s so far', $time_spent)); if ($usertime->getObjectPHID() !== null && $usertime->getUserPHID() === $viewer->getPHID()) { $item->addAction(id(new PHUIListItemView())->setIcon('fa-stop')->addSigil('phrequent-stop-tracking')->setWorkflow(true)->setRenderNameAsTooltip(true)->setName(pht('Stop'))->setHref('/phrequent/track/stop/' . $usertime->getObjectPHID() . '/')); } $item->setBarColor('green'); } $view->addItem($item); } return $view; }