public function render() { $rows = array(); $rowc = array(); // TODO: Experiment with path stack rendering. // TODO: Copy Away and Move Away are rendered junkily still. foreach ($this->pathChanges as $id => $change) { $path = $change->getPath(); $hash = substr(md5($path), 0, 8); if ($change->getFileType() == DifferentialChangeType::FILE_DIRECTORY) { $path .= '/'; } if (isset($this->renderingReferences[$id])) { $path_column = javelin_render_tag('a', array('href' => '#' . $hash, 'meta' => array('id' => 'diff-' . $hash, 'ref' => $this->renderingReferences[$id]), 'sigil' => 'differential-load'), phutil_escape_html($path)); } else { $path_column = phutil_escape_html($path); } $rows[] = array($this->linkHistory($change->getPath()), $this->linkBrowse($change->getPath()), $this->linkChange($change->getChangeType(), $change->getFileType(), $change->getPath()), $path_column); $row_class = null; foreach ($this->ownersPaths as $owners_path) { $owners_path = $owners_path->getPath(); if (strncmp('/' . $path, $owners_path, strlen($owners_path)) == 0) { $row_class = 'highlighted'; break; } } $rowc[] = $row_class; } $view = new AphrontTableView($rows); $view->setHeaders(array('History', 'Browse', 'Change', 'Path')); $view->setColumnClasses(array('', '', '', 'wide')); $view->setRowClasses($rowc); $view->setNoDataString('This change has not been fully parsed yet.'); return $view->render(); }
public function renderConfigurationFooter() { $hashers = PhabricatorPasswordHasher::getAllHashers(); $hashers = msort($hashers, 'getStrength'); $hashers = array_reverse($hashers); $yes = phutil_tag('strong', array('style' => 'color: #009900'), pht('Yes')); $no = phutil_tag('strong', array('style' => 'color: #990000'), pht('Not Installed')); $best_hasher_name = null; try { $best_hasher = PhabricatorPasswordHasher::getBestHasher(); $best_hasher_name = $best_hasher->getHashName(); } catch (PhabricatorPasswordHasherUnavailableException $ex) { // There are no suitable hashers. The user might be able to enable some, // so we don't want to fatal here. We'll fatal when users try to actually // use this stuff if it isn't fixed before then. Until then, we just // don't highlight a row. In practice, at least one hasher should always // be available. } $rows = array(); $rowc = array(); foreach ($hashers as $hasher) { $is_installed = $hasher->canHashPasswords(); $rows[] = array($hasher->getHumanReadableName(), $hasher->getHashName(), $hasher->getHumanReadableStrength(), $is_installed ? $yes : $no, $is_installed ? null : $hasher->getInstallInstructions()); $rowc[] = $best_hasher_name == $hasher->getHashName() ? 'highlighted' : null; } $table = new AphrontTableView($rows); $table->setRowClasses($rowc); $table->setHeaders(array(pht('Algorithm'), pht('Name'), pht('Strength'), pht('Installed'), pht('Install Instructions'))); $table->setColumnClasses(array('', '', '', '', 'wide')); $header = id(new PHUIHeaderView())->setHeader(pht('Password Hash Algorithms'))->setSubheader(pht('Stronger algorithms are listed first. The highlighted algorithm ' . 'will be used when storing new hashes. Older hashes will be ' . 'upgraded to the best algorithm over time.')); return id(new PHUIObjectBoxView())->setHeader($header)->appendChild($table); }
public function render() { $drequest = $this->getDiffusionRequest(); $current_branch = $drequest->getBranch(); $rows = array(); $rowc = array(); foreach ($this->branches as $branch) { $commit = idx($this->commits, $branch->getHeadCommitIdentifier()); if ($commit) { $details = $commit->getCommitData()->getCommitMessage(); $details = idx(explode("\n", $details), 0); $details = substr($details, 0, 80); $datetime = phabricator_datetime($commit->getEpoch(), $this->user); } else { $datetime = null; $details = null; } $rows[] = array(phutil_render_tag('a', array('href' => $drequest->generateURI(array('action' => 'history', 'branch' => $branch->getName()))), 'History'), phutil_render_tag('a', array('href' => $drequest->generateURI(array('action' => 'browse', 'branch' => $branch->getName()))), phutil_escape_html($branch->getName())), self::linkCommit($drequest->getRepository(), $branch->getHeadCommitIdentifier()), $datetime, AphrontTableView::renderSingleDisplayLine(phutil_escape_html($details))); if ($branch->getName() == $current_branch) { $rowc[] = 'highlighted'; } else { $rowc[] = null; } } $view = new AphrontTableView($rows); $view->setHeaders(array('History', 'Branch', 'Head', 'Modified', 'Details')); $view->setColumnClasses(array('', 'pri', '', '', 'wide')); $view->setRowClasses($rowc); return $view->render(); }
public function render() { $drequest = $this->getDiffusionRequest(); $current_branch = $drequest->getBranch(); $repository = $drequest->getRepository(); Javelin::initBehavior('phabricator-tooltips'); $doc_href = PhabricatorEnv::getDoclink('Diffusion User Guide: Autoclose'); $rows = array(); $rowc = array(); foreach ($this->branches as $branch) { $commit = idx($this->commits, $branch->getCommitIdentifier()); if ($commit) { $details = $commit->getSummary(); $datetime = phabricator_datetime($commit->getEpoch(), $this->user); } else { $datetime = null; $details = null; } switch ($repository->shouldSkipAutocloseBranch($branch->getShortName())) { case PhabricatorRepository::BECAUSE_REPOSITORY_IMPORTING: $icon = 'fa-times bluegrey'; $tip = pht('Repository Importing'); break; case PhabricatorRepository::BECAUSE_AUTOCLOSE_DISABLED: $icon = 'fa-times bluegrey'; $tip = pht('Repository Autoclose Disabled'); break; case PhabricatorRepository::BECAUSE_BRANCH_UNTRACKED: $icon = 'fa-times bluegrey'; $tip = pht('Branch Untracked'); break; case PhabricatorRepository::BECAUSE_BRANCH_NOT_AUTOCLOSE: $icon = 'fa-times bluegrey'; $tip = pht('Branch Autoclose Disabled'); break; case null: $icon = 'fa-check bluegrey'; $tip = pht('Autoclose Enabled'); break; default: $icon = 'fa-question'; $tip = pht('Status Unknown'); break; } $status_icon = id(new PHUIIconView())->setIconFont($icon)->addSigil('has-tooltip')->setHref($doc_href)->setMetadata(array('tip' => $tip, 'size' => 200)); $rows[] = array(phutil_tag('a', array('href' => $drequest->generateURI(array('action' => 'history', 'branch' => $branch->getShortName()))), pht('History')), phutil_tag('a', array('href' => $drequest->generateURI(array('action' => 'browse', 'branch' => $branch->getShortName()))), $branch->getShortName()), self::linkCommit($drequest->getRepository(), $branch->getCommitIdentifier()), $status_icon, $datetime, AphrontTableView::renderSingleDisplayLine($details)); if ($branch->getShortName() == $current_branch) { $rowc[] = 'highlighted'; } else { $rowc[] = null; } } $view = new AphrontTableView($rows); $view->setHeaders(array(pht('History'), pht('Branch'), pht('Head'), pht(''), pht('Modified'), pht('Details'))); $view->setColumnClasses(array('', 'pri', '', '', '', 'wide')); $view->setRowClasses($rowc); return $view->render(); }
public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $upload_panel = $this->renderUploadPanel(); $author = null; $author_username = $request->getStr('author'); if ($author_username) { $author = id(new PhabricatorUser())->loadOneWhere('userName = %s', $author_username); if (!$author) { return id(new Aphront404Response()); } $title = 'Files Uploaded by ' . phutil_escape_html($author->getUsername()); } else { $title = 'Files'; } $pager = new AphrontPagerView(); $pager->setOffset($request->getInt('page')); if ($author) { $files = id(new PhabricatorFile())->loadAllWhere('authorPHID = %s ORDER BY id DESC LIMIT %d, %d', $author->getPHID(), $pager->getOffset(), $pager->getPageSize() + 1); } else { $files = id(new PhabricatorFile())->loadAllWhere('1 = 1 ORDER BY id DESC LIMIT %d, %d', $pager->getOffset(), $pager->getPageSize() + 1); } $files = $pager->sliceResults($files); $pager->setURI($request->getRequestURI(), 'page'); $phids = mpull($files, 'getAuthorPHID'); $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles(); $highlighted = $request->getStr('h'); $highlighted = explode('-', $highlighted); $highlighted = array_fill_keys($highlighted, true); $rows = array(); $rowc = array(); foreach ($files as $file) { if ($file->isViewableInBrowser()) { $view_button = phutil_render_tag('a', array('class' => 'small button grey', 'href' => '/file/view/' . $file->getPHID() . '/'), 'View'); } else { $view_button = null; } if (isset($highlighted[$file->getID()])) { $rowc[] = 'highlighted'; } else { $rowc[] = ''; } $rows[] = array(phutil_escape_html('F' . $file->getID()), $file->getAuthorPHID() ? $handles[$file->getAuthorPHID()]->renderLink() : null, phutil_render_tag('a', array('href' => $file->getViewURI()), phutil_escape_html($file->getName())), phutil_escape_html(number_format($file->getByteSize()) . ' bytes'), phutil_render_tag('a', array('class' => 'small button grey', 'href' => '/file/info/' . $file->getPHID() . '/'), 'Info'), $view_button, phutil_render_tag('a', array('class' => 'small button grey', 'href' => '/file/download/' . $file->getPHID() . '/'), 'Download'), phabricator_date($file->getDateCreated(), $user), phabricator_time($file->getDateCreated(), $user)); } $table = new AphrontTableView($rows); $table->setRowClasses($rowc); $table->setHeaders(array('File ID', 'Author', 'Name', 'Size', '', '', '', 'Created', '')); $table->setColumnClasses(array(null, '', 'wide pri', 'right', 'action', 'action', 'action', '', 'right')); $panel = new AphrontPanelView(); $panel->appendChild($table); $panel->setHeader($title); $panel->appendChild($pager); return $this->buildStandardPageResponse(array($upload_panel, $panel), array('title' => 'Files', 'tab' => 'files')); }
public function processRequest(AphrontRequest $request) { if ($request->getExists('new')) { return $this->processNew($request); } if ($request->getExists('edit')) { return $this->processEdit($request); } if ($request->getExists('delete')) { return $this->processDelete($request); } $user = $this->getUser(); $viewer = $request->getUser(); $factors = id(new PhabricatorAuthFactorConfig())->loadAllWhere('userPHID = %s', $user->getPHID()); $rows = array(); $rowc = array(); $highlight_id = $request->getInt('id'); foreach ($factors as $factor) { $impl = $factor->getImplementation(); if ($impl) { $type = $impl->getFactorName(); } else { $type = $factor->getFactorKey(); } if ($factor->getID() == $highlight_id) { $rowc[] = 'highlighted'; } else { $rowc[] = null; } $rows[] = array(javelin_tag('a', array('href' => $this->getPanelURI('?edit=' . $factor->getID()), 'sigil' => 'workflow'), $factor->getFactorName()), $type, phabricator_datetime($factor->getDateCreated(), $viewer), javelin_tag('a', array('href' => $this->getPanelURI('?delete=' . $factor->getID()), 'sigil' => 'workflow', 'class' => 'small grey button'), pht('Remove'))); } $table = new AphrontTableView($rows); $table->setNoDataString(pht("You haven't added any authentication factors to your account yet.")); $table->setHeaders(array(pht('Name'), pht('Type'), pht('Created'), '')); $table->setColumnClasses(array('wide pri', '', 'right', 'action')); $table->setRowClasses($rowc); $table->setDeviceVisibility(array(true, false, false, true)); $panel = new PHUIObjectBoxView(); $header = new PHUIHeaderView(); $help_uri = PhabricatorEnv::getDoclink('User Guide: Multi-Factor Authentication'); $help_icon = id(new PHUIIconView())->setIconFont('fa-info-circle'); $help_button = id(new PHUIButtonView())->setText(pht('Help'))->setHref($help_uri)->setTag('a')->setIcon($help_icon); $create_icon = id(new PHUIIconView())->setIconFont('fa-plus'); $create_button = id(new PHUIButtonView())->setText(pht('Add Authentication Factor'))->setHref($this->getPanelURI('?new=true'))->setTag('a')->setWorkflow(true)->setIcon($create_icon); $header->setHeader(pht('Authentication Factors')); $header->addActionLink($help_button); $header->addActionLink($create_button); $panel->setHeader($header); $panel->setTable($table); return $panel; }
private function buildClientList($rows, $rowc, $title) { $table = new AphrontTableView($rows); $table->setRowClasses($rowc); $table->setHeaders(array('Client', 'ID', 'Secret', 'Redirect URI', '')); $table->setColumnClasses(array('', '', '', '', 'action')); if (empty($rows)) { $table->setNoDataString('You have not created any clients for this OAuthServer.'); } $panel = new AphrontPanelView(); $panel->appendChild($table); $panel->setHeader($title); return $panel; }
private function buildClientAuthorizationList($rows, $rowc, $title) { $table = new AphrontTableView($rows); $table->setRowClasses($rowc); $table->setHeaders(array('Client', 'Scope', 'Created', 'Updated', '')); $table->setColumnClasses(array('wide pri', '', '', '', 'action')); if (empty($rows)) { $table->setNoDataString('You have not authorized any clients for this OAuthServer.'); } $panel = new AphrontPanelView(); $panel->appendChild($table); $panel->setHeader($title); return $panel; }
public function processRequest(AphrontRequest $request) { $viewer = $request->getUser(); // TODO: It would be nice to simply disable this panel, but we can't do // viewer-based checks for enabled panels right now. $app_class = 'PhabricatorOAuthServerApplication'; $installed = PhabricatorApplication::isClassInstalledForViewer($app_class, $viewer); if (!$installed) { $dialog = id(new AphrontDialogView())->setUser($viewer)->setTitle(pht('OAuth Not Available'))->appendParagraph(pht('You do not have access to OAuth authorizations.'))->addCancelButton('/settings/'); return id(new AphrontDialogResponse())->setDialog($dialog); } $authorizations = id(new PhabricatorOAuthClientAuthorizationQuery())->setViewer($viewer)->withUserPHIDs(array($viewer->getPHID()))->execute(); $authorizations = mpull($authorizations, null, 'getID'); $panel_uri = $this->getPanelURI(); $revoke = $request->getInt('revoke'); if ($revoke) { if (empty($authorizations[$revoke])) { return new Aphront404Response(); } if ($request->isFormPost()) { $authorizations[$revoke]->delete(); return id(new AphrontRedirectResponse())->setURI($panel_uri); } $dialog = id(new AphrontDialogView())->setUser($viewer)->setTitle(pht('Revoke Authorization?'))->appendParagraph(pht('This application will no longer be able to access Phabricator ' . 'on your behalf.'))->addSubmitButton(pht('Revoke Authorization'))->addCancelButton($panel_uri); return id(new AphrontDialogResponse())->setDialog($dialog); } $highlight = $request->getInt('id'); $rows = array(); $rowc = array(); foreach ($authorizations as $authorization) { if ($highlight == $authorization->getID()) { $rowc[] = 'highlighted'; } else { $rowc[] = null; } $button = javelin_tag('a', array('href' => $this->getPanelURI('?revoke=' . $authorization->getID()), 'class' => 'small grey button', 'sigil' => 'workflow'), pht('Revoke')); $rows[] = array(phutil_tag('a', array('href' => $authorization->getClient()->getViewURI()), $authorization->getClient()->getName()), $authorization->getScopeString(), phabricator_datetime($authorization->getDateCreated(), $viewer), phabricator_datetime($authorization->getDateModified(), $viewer), $button); } $table = new AphrontTableView($rows); $table->setNoDataString(pht("You haven't authorized any OAuth applications.")); $table->setRowClasses($rowc); $table->setHeaders(array(pht('Application'), pht('Scope'), pht('Created'), pht('Updated'), null)); $table->setColumnClasses(array('pri', 'wide', 'right', 'right', 'action')); $header = id(new PHUIHeaderView())->setHeader(pht('OAuth Application Authorizations')); $panel = id(new PHUIObjectBoxView())->setHeader($header)->appendChild($table); return $panel; }
public function render() { $drequest = $this->getDiffusionRequest(); $current_branch = $drequest->getBranch(); $rows = array(); $rowc = array(); foreach ($this->branches as $branch) { $rows[] = array(phutil_render_tag('a', array('href' => $drequest->generateURI(array('action' => 'branch', 'branch' => $branch->getName()))), phutil_escape_html($branch->getName())), self::linkCommit($drequest->getRepository(), $branch->getHeadCommitIdentifier())); if ($branch->getName() == $current_branch) { $rowc[] = 'highlighted'; } else { $rowc[] = null; } } $view = new AphrontTableView($rows); $view->setHeaders(array('Branch', 'Head')); $view->setColumnClasses(array('wide')); $view->setRowClasses($rowc); return $view->render(); }
public function processRequest(AphrontRequest $request) { $viewer = $request->getUser(); $accounts = id(new PhabricatorExternalAccountQuery())->setViewer($viewer)->withUserPHIDs(array($viewer->getPHID()))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->execute(); $identity_phids = mpull($accounts, 'getPHID'); $identity_phids[] = $viewer->getPHID(); $sessions = id(new PhabricatorAuthSessionQuery())->setViewer($viewer)->withIdentityPHIDs($identity_phids)->execute(); $handles = id(new PhabricatorHandleQuery())->setViewer($viewer)->withPHIDs($identity_phids)->execute(); $current_key = PhabricatorHash::digest($request->getCookie(PhabricatorCookies::COOKIE_SESSION)); $rows = array(); $rowc = array(); foreach ($sessions as $session) { $is_current = phutil_hashes_are_identical($session->getSessionKey(), $current_key); if ($is_current) { $rowc[] = 'highlighted'; $button = phutil_tag('a', array('class' => 'small grey button disabled'), pht('Current')); } else { $rowc[] = null; $button = javelin_tag('a', array('href' => '/auth/session/terminate/' . $session->getID() . '/', 'class' => 'small grey button', 'sigil' => 'workflow'), pht('Terminate')); } $hisec = $session->getHighSecurityUntil() - time(); $rows[] = array($handles[$session->getUserPHID()]->renderLink(), substr($session->getSessionKey(), 0, 6), $session->getType(), $hisec > 0 ? phutil_format_relative_time($hisec) : null, phabricator_datetime($session->getSessionStart(), $viewer), phabricator_date($session->getSessionExpires(), $viewer), $button); } $table = new AphrontTableView($rows); $table->setNoDataString(pht("You don't have any active sessions.")); $table->setRowClasses($rowc); $table->setHeaders(array(pht('Identity'), pht('Session'), pht('Type'), pht('HiSec'), pht('Created'), pht('Expires'), pht(''))); $table->setColumnClasses(array('wide', 'n', '', 'right', 'right', 'right', 'action')); $terminate_icon = id(new PHUIIconView())->setIconFont('fa-exclamation-triangle'); $terminate_button = id(new PHUIButtonView())->setText(pht('Terminate All Sessions'))->setHref('/auth/session/terminate/all/')->setTag('a')->setWorkflow(true)->setIcon($terminate_icon); $header = id(new PHUIHeaderView())->setHeader(pht('Active Login Sessions'))->addActionLink($terminate_button); $hisec = $viewer->getSession()->getHighSecurityUntil() - time(); if ($hisec > 0) { $hisec_icon = id(new PHUIIconView())->setIconFont('fa-lock'); $hisec_button = id(new PHUIButtonView())->setText(pht('Leave High Security'))->setHref('/auth/session/downgrade/')->setTag('a')->setWorkflow(true)->setIcon($hisec_icon); $header->addActionLink($hisec_button); } $panel = id(new PHUIObjectBoxView())->setHeader($header)->setTable($table); return $panel; }
private function renderList() { $table = new AphrontTableView($this->getListRows()); $table->setRowClasses($this->getListRowClasses()); $table->setHeaders(array('File ID', 'Author', 'Name', 'Size', '', '', 'Created', '')); $table->setColumnClasses(array(null, '', 'wide pri', 'right', 'action', 'action', '', 'right')); $panel = new AphrontPanelView(); $panel->appendChild($table); $panel->setHeader($this->getListHeader()); if ($this->showListPager()) { $panel->appendChild($this->getListPager()); } return $panel; }
public function processRequest(AphrontRequest $request) { $user = $this->getUser(); $editable = PhabricatorEnv::getEnvConfig('account.editable'); $uri = $request->getRequestURI(); $uri->setQueryParams(array()); if ($editable) { $new = $request->getStr('new'); if ($new) { return $this->returnNewAddressResponse($request, $uri, $new); } $delete = $request->getInt('delete'); if ($delete) { return $this->returnDeleteAddressResponse($request, $uri, $delete); } } $verify = $request->getInt('verify'); if ($verify) { return $this->returnVerifyAddressResponse($request, $uri, $verify); } $primary = $request->getInt('primary'); if ($primary) { return $this->returnPrimaryAddressResponse($request, $uri, $primary); } $emails = id(new PhabricatorUserEmail())->loadAllWhere('userPHID = %s ORDER BY address', $user->getPHID()); $rowc = array(); $rows = array(); foreach ($emails as $email) { $button_verify = javelin_tag('a', array('class' => 'button small grey', 'href' => $uri->alter('verify', $email->getID()), 'sigil' => 'workflow'), pht('Verify')); $button_make_primary = javelin_tag('a', array('class' => 'button small grey', 'href' => $uri->alter('primary', $email->getID()), 'sigil' => 'workflow'), pht('Make Primary')); $button_remove = javelin_tag('a', array('class' => 'button small grey', 'href' => $uri->alter('delete', $email->getID()), 'sigil' => 'workflow'), pht('Remove')); $button_primary = phutil_tag('a', array('class' => 'button small disabled'), pht('Primary')); if (!$email->getIsVerified()) { $action = $button_verify; } else { if ($email->getIsPrimary()) { $action = $button_primary; } else { $action = $button_make_primary; } } if ($email->getIsPrimary()) { $remove = $button_primary; $rowc[] = 'highlighted'; } else { $remove = $button_remove; $rowc[] = null; } $rows[] = array($email->getAddress(), $action, $remove); } $table = new AphrontTableView($rows); $table->setHeaders(array(pht('Email'), pht('Status'), pht('Remove'))); $table->setColumnClasses(array('wide', 'action', 'action')); $table->setRowClasses($rowc); $table->setColumnVisibility(array(true, true, $editable)); $view = new PHUIObjectBoxView(); $header = new PHUIHeaderView(); $header->setHeader(pht('Email Addresses')); if ($editable) { $button = new PHUIButtonView(); $button->setText(pht('Add New Address')); $button->setTag('a'); $button->setHref($uri->alter('new', 'true')); $button->setIcon('fa-plus'); $button->addSigil('workflow'); $header->addActionLink($button); } $view->setHeader($header); $view->setTable($table); return $view; }
public function render() { $user = $this->user; $authority = array_fill_keys($this->authorityPHIDs, true); $rowc = array(); $last = null; $rows = array(); foreach ($this->audits as $audit) { $commit_phid = $audit->getCommitPHID(); if ($last == $commit_phid) { $commit_name = null; $commit_desc = null; } else { $commit_name = $this->getHandle($commit_phid)->renderLink(); $commit_desc = $this->getCommitDescription($commit_phid); $last = $commit_phid; } $reasons = $audit->getAuditReasons(); foreach ($reasons as $key => $reason) { $reasons[$key] = phutil_escape_html($reason); } $reasons = implode('<br />', $reasons); $status_code = $audit->getAuditStatus(); $status = PhabricatorAuditStatusConstants::getStatusName($status_code); $auditor_handle = $this->getHandle($audit->getAuditorPHID()); $rows[] = array($commit_name, phutil_escape_html($commit_desc), $auditor_handle->renderLink(), phutil_escape_html($status), $reasons); $row_class = null; $has_authority = !empty($authority[$audit->getAuditorPHID()]); if ($has_authority) { $commit_author = $this->commits[$commit_phid]->getAuthorPHID(); // You don't have authority over package and project audits on your own // commits. $auditor_is_user = $audit->getAuditorPHID() == $user->getPHID(); $user_is_author = $commit_author == $user->getPHID(); if ($auditor_is_user || !$user_is_author) { $row_class = 'highlighted'; } } $rowc[] = $row_class; } $table = new AphrontTableView($rows); $table->setHeaders(array('Commit', 'Description', 'Auditor', 'Status', 'Details')); $table->setColumnClasses(array('pri', $this->showDescriptions ? 'wide' : '', '', '', $this->showDescriptions ? '' : 'wide')); $table->setRowClasses($rowc); $table->setColumnVisibility(array($this->showDescriptions, $this->showDescriptions, true, true, true)); if ($this->noDataString) { $table->setNoDataString($this->noDataString); } return $table->render(); }
/** * @param string[] $rowc */ private function statsTableView($rows, $rowc) { $table = new AphrontTableView($rows); $table->setRowClasses($rowc); $table->setHeaders(array(pht('Period'), pht('Opened'), pht('Closed'), pht('Change'))); $table->setColumnClasses(array('left narrow', 'center narrow', 'center narrow', 'center narrow')); return $table; }
public function render() { $drequest = $this->getDiffusionRequest(); $current_branch = $drequest->getBranch(); $repository = $drequest->getRepository(); $commits = $this->commits; $viewer = $this->getUser(); $buildables = $this->loadBuildables($commits); $have_builds = false; $can_close_branches = $repository->isHg(); Javelin::initBehavior('phabricator-tooltips'); $doc_href = PhabricatorEnv::getDoclink('Diffusion User Guide: Autoclose'); $rows = array(); $rowc = array(); foreach ($this->branches as $branch) { $commit = idx($commits, $branch->getCommitIdentifier()); if ($commit) { $details = $commit->getSummary(); $datetime = $viewer->formatShortDateTime($commit->getEpoch()); $buildable = idx($buildables, $commit->getPHID()); if ($buildable) { $build_status = $this->renderBuildable($buildable); $have_builds = true; } else { $build_status = null; } } else { $datetime = null; $details = null; $build_status = null; } switch ($repository->shouldSkipAutocloseBranch($branch->getShortName())) { case PhabricatorRepository::BECAUSE_REPOSITORY_IMPORTING: $icon = 'fa-times bluegrey'; $tip = pht('Repository Importing'); break; case PhabricatorRepository::BECAUSE_AUTOCLOSE_DISABLED: $icon = 'fa-times bluegrey'; $tip = pht('Repository Autoclose Disabled'); break; case PhabricatorRepository::BECAUSE_BRANCH_UNTRACKED: $icon = 'fa-times bluegrey'; $tip = pht('Branch Untracked'); break; case PhabricatorRepository::BECAUSE_BRANCH_NOT_AUTOCLOSE: $icon = 'fa-times bluegrey'; $tip = pht('Branch Autoclose Disabled'); break; case null: $icon = 'fa-check bluegrey'; $tip = pht('Autoclose Enabled'); break; default: $icon = 'fa-question'; $tip = pht('Status Unknown'); break; } $status_icon = id(new PHUIIconView())->setIcon($icon)->addSigil('has-tooltip')->setHref($doc_href)->setMetadata(array('tip' => $tip, 'size' => 200)); $fields = $branch->getRawFields(); $closed = idx($fields, 'closed'); if ($closed) { $status = pht('Closed'); } else { $status = pht('Open'); } $rows[] = array($this->linkBranchHistory($branch->getShortName()), phutil_tag('a', array('href' => $drequest->generateURI(array('action' => 'browse', 'branch' => $branch->getShortName()))), $branch->getShortName()), self::linkCommit($drequest->getRepository(), $branch->getCommitIdentifier()), $build_status, $status, AphrontTableView::renderSingleDisplayLine($details), $status_icon, $datetime); if ($branch->getShortName() == $current_branch) { $rowc[] = 'highlighted'; } else { $rowc[] = null; } } $view = new AphrontTableView($rows); $view->setHeaders(array(null, pht('Branch'), pht('Head'), null, pht('State'), pht('Details'), null, pht('Committed'))); $view->setColumnClasses(array('', 'pri', '', 'icon', '', 'wide', '', 'right')); $view->setColumnVisibility(array(true, true, true, $have_builds, $can_close_branches)); $view->setRowClasses($rowc); return $view->render(); }
public function renderBurn() { $request = $this->getRequest(); $viewer = $request->getUser(); $handle = null; $project_phid = $request->getStr('project'); if ($project_phid) { $phids = array($project_phid); $handles = $this->loadViewerHandles($phids); $handle = $handles[$project_phid]; } $table = new ManiphestTransaction(); $conn = $table->establishConnection('r'); $joins = ''; if ($project_phid) { $joins = qsprintf($conn, 'JOIN %T t ON x.objectPHID = t.phid JOIN %T p ON p.src = t.phid AND p.type = %d AND p.dst = %s', id(new ManiphestTask())->getTableName(), PhabricatorEdgeConfig::TABLE_NAME_EDGE, PhabricatorProjectObjectHasProjectEdgeType::EDGECONST, $project_phid); } $data = queryfx_all($conn, 'SELECT x.oldValue, x.newValue, x.dateCreated FROM %T x %Q WHERE transactionType = %s ORDER BY x.dateCreated ASC', $table->getTableName(), $joins, ManiphestTransaction::TYPE_STATUS); $stats = array(); $day_buckets = array(); $open_tasks = array(); foreach ($data as $key => $row) { // NOTE: Hack to avoid json_decode(). $oldv = trim($row['oldValue'], '"'); $newv = trim($row['newValue'], '"'); if ($oldv == 'null') { $old_is_open = false; } else { $old_is_open = ManiphestTaskStatus::isOpenStatus($oldv); } $new_is_open = ManiphestTaskStatus::isOpenStatus($newv); $is_open = $new_is_open && !$old_is_open; $is_close = $old_is_open && !$new_is_open; $data[$key]['_is_open'] = $is_open; $data[$key]['_is_close'] = $is_close; if (!$is_open && !$is_close) { // This is either some kind of bogus event, or a resolution change // (e.g., resolved -> invalid). Just skip it. continue; } $day_bucket = phabricator_format_local_time($row['dateCreated'], $viewer, 'Yz'); $day_buckets[$day_bucket] = $row['dateCreated']; if (empty($stats[$day_bucket])) { $stats[$day_bucket] = array('open' => 0, 'close' => 0); } $stats[$day_bucket][$is_close ? 'close' : 'open']++; } $template = array('open' => 0, 'close' => 0); $rows = array(); $rowc = array(); $last_month = null; $last_month_epoch = null; $last_week = null; $last_week_epoch = null; $week = null; $month = null; $last = last_key($stats) - 1; $period = $template; foreach ($stats as $bucket => $info) { $epoch = $day_buckets[$bucket]; $week_bucket = phabricator_format_local_time($epoch, $viewer, 'YW'); if ($week_bucket != $last_week) { if ($week) { $rows[] = $this->formatBurnRow(pht('Week of %s', phabricator_date($last_week_epoch, $viewer)), $week); $rowc[] = 'week'; } $week = $template; $last_week = $week_bucket; $last_week_epoch = $epoch; } $month_bucket = phabricator_format_local_time($epoch, $viewer, 'Ym'); if ($month_bucket != $last_month) { if ($month) { $rows[] = $this->formatBurnRow(phabricator_format_local_time($last_month_epoch, $viewer, 'F, Y'), $month); $rowc[] = 'month'; } $month = $template; $last_month = $month_bucket; $last_month_epoch = $epoch; } $rows[] = $this->formatBurnRow(phabricator_date($epoch, $viewer), $info); $rowc[] = null; $week['open'] += $info['open']; $week['close'] += $info['close']; $month['open'] += $info['open']; $month['close'] += $info['close']; $period['open'] += $info['open']; $period['close'] += $info['close']; } if ($week) { $rows[] = $this->formatBurnRow(pht('Week To Date'), $week); $rowc[] = 'week'; } if ($month) { $rows[] = $this->formatBurnRow(pht('Month To Date'), $month); $rowc[] = 'month'; } $rows[] = $this->formatBurnRow(pht('All Time'), $period); $rowc[] = 'aggregate'; $rows = array_reverse($rows); $rowc = array_reverse($rowc); $table = new AphrontTableView($rows); $table->setRowClasses($rowc); $table->setHeaders(array(pht('Period'), pht('Opened'), pht('Closed'), pht('Change'))); $table->setColumnClasses(array('right wide', 'n', 'n', 'n')); if ($handle) { $inst = pht('NOTE: This table reflects tasks currently in ' . 'the project. If a task was opened in the past but added to ' . 'the project recently, it is counted on the day it was ' . 'opened, not the day it was categorized. If a task was part ' . 'of this project in the past but no longer is, it is not ' . 'counted at all.'); $header = pht('Task Burn Rate for Project %s', $handle->renderLink()); $caption = phutil_tag('p', array(), $inst); } else { $header = pht('Task Burn Rate for All Tasks'); $caption = null; } if ($caption) { $caption = id(new PHUIInfoView())->appendChild($caption)->setSeverity(PHUIInfoView::SEVERITY_NOTICE); } $panel = new PHUIObjectBoxView(); $panel->setHeaderText($header); if ($caption) { $panel->setInfoView($caption); } $panel->setTable($table); $tokens = array(); if ($handle) { $tokens = array($handle); } $filter = $this->renderReportFilters($tokens, $has_window = false); $id = celerity_generate_unique_node_id(); $chart = phutil_tag('div', array('id' => $id, 'style' => 'border: 1px solid #BFCFDA; ' . 'background-color: #fff; ' . 'margin: 8px 16px; ' . 'height: 400px; '), ''); list($burn_x, $burn_y) = $this->buildSeries($data); require_celerity_resource('d3'); require_celerity_resource('phui-chart-css'); Javelin::initBehavior('line-chart', array('hardpoint' => $id, 'x' => array($burn_x), 'y' => array($burn_y), 'xformat' => 'epoch', 'yformat' => 'int')); $box = id(new PHUIObjectBoxView())->setHeaderText(pht('Burnup Rate'))->appendChild($chart); return array($filter, $box, $panel); }
public function render() { $rowc = array(); $last = null; $rows = array(); foreach ($this->audits as $audit) { $commit_phid = $audit->getCommitPHID(); $committed = null; if ($last == $commit_phid) { $commit_name = null; $commit_desc = null; } else { $commit_name = $this->getHandle($commit_phid)->renderLink(); $commit_desc = $this->getCommitDescription($commit_phid); $commit = idx($this->commits, $commit_phid); if ($commit && $this->user) { $committed = phabricator_datetime($commit->getEpoch(), $this->user); } $last = $commit_phid; } $reasons = $audit->getAuditReasons(); foreach ($reasons as $key => $reason) { $reasons[$key] = phutil_escape_html($reason); } $reasons = implode('<br />', $reasons); $status_code = $audit->getAuditStatus(); $status = PhabricatorAuditStatusConstants::getStatusName($status_code); $auditor_handle = $this->getHandle($audit->getAuditorPHID()); $rows[] = array($commit_name, phutil_escape_html($commit_desc), $committed, $auditor_handle->renderLink(), phutil_escape_html($status), $reasons); $row_class = null; if (array_key_exists($audit->getID(), $this->getHighlightedAudits())) { $row_class = 'highlighted'; } $rowc[] = $row_class; } $table = new AphrontTableView($rows); $table->setHeaders(array('Commit', 'Description', 'Committed', 'Auditor', 'Status', 'Details')); $table->setColumnClasses(array('pri', $this->showDescriptions ? 'wide' : '', '', '', '', $this->showDescriptions ? '' : 'wide')); $table->setRowClasses($rowc); $table->setColumnVisibility(array($this->showDescriptions, $this->showDescriptions, $this->showDescriptions, true, true, true)); if ($this->noDataString) { $table->setNoDataString($this->noDataString); } return $table->render(); }
public function renderBurn() { $request = $this->getRequest(); $user = $request->getUser(); $handle = null; $project_phid = $request->getStr('project'); if ($project_phid) { $phids = array($project_phid); $handles = $this->loadViewerHandles($phids); $handle = $handles[$project_phid]; } $table = new ManiphestTransaction(); $conn = $table->establishConnection('r'); $joins = ''; if ($project_phid) { $joins = qsprintf($conn, 'JOIN %T t ON x.taskID = t.id JOIN %T p ON p.taskPHID = t.phid AND p.projectPHID = %s', id(new ManiphestTask())->getTableName(), id(new ManiphestTaskProject())->getTableName(), $project_phid); } $data = queryfx_all($conn, 'SELECT x.oldValue, x.newValue, x.dateCreated FROM %T x %Q WHERE transactionType = %s ORDER BY x.dateCreated ASC', $table->getTableName(), $joins, ManiphestTransactionType::TYPE_STATUS); $stats = array(); $day_buckets = array(); $open_tasks = array(); foreach ($data as $key => $row) { // NOTE: Hack to avoid json_decode(). $oldv = trim($row['oldValue'], '"'); $newv = trim($row['newValue'], '"'); $old_is_open = $oldv === (string) ManiphestTaskStatus::STATUS_OPEN; $new_is_open = $newv === (string) ManiphestTaskStatus::STATUS_OPEN; $is_open = $new_is_open && !$old_is_open; $is_close = $old_is_open && !$new_is_open; $data[$key]['_is_open'] = $is_open; $data[$key]['_is_close'] = $is_close; if (!$is_open && !$is_close) { // This is either some kind of bogus event, or a resolution change // (e.g., resolved -> invalid). Just skip it. continue; } $day_bucket = phabricator_format_local_time($row['dateCreated'], $user, 'Yz'); $day_buckets[$day_bucket] = $row['dateCreated']; if (empty($stats[$day_bucket])) { $stats[$day_bucket] = array('open' => 0, 'close' => 0); } $stats[$day_bucket][$is_close ? 'close' : 'open']++; } $template = array('open' => 0, 'close' => 0); $rows = array(); $rowc = array(); $last_month = null; $last_month_epoch = null; $last_week = null; $last_week_epoch = null; $week = null; $month = null; $last = last_key($stats) - 1; $period = $template; foreach ($stats as $bucket => $info) { $epoch = $day_buckets[$bucket]; $week_bucket = phabricator_format_local_time($epoch, $user, 'YW'); if ($week_bucket != $last_week) { if ($week) { $rows[] = $this->formatBurnRow('Week of ' . phabricator_date($last_week_epoch, $user), $week); $rowc[] = 'week'; } $week = $template; $last_week = $week_bucket; $last_week_epoch = $epoch; } $month_bucket = phabricator_format_local_time($epoch, $user, 'Ym'); if ($month_bucket != $last_month) { if ($month) { $rows[] = $this->formatBurnRow(phabricator_format_local_time($last_month_epoch, $user, 'F, Y'), $month); $rowc[] = 'month'; } $month = $template; $last_month = $month_bucket; $last_month_epoch = $epoch; } $rows[] = $this->formatBurnRow(phabricator_date($epoch, $user), $info); $rowc[] = null; $week['open'] += $info['open']; $week['close'] += $info['close']; $month['open'] += $info['open']; $month['close'] += $info['close']; $period['open'] += $info['open']; $period['close'] += $info['close']; } if ($week) { $rows[] = $this->formatBurnRow('Week To Date', $week); $rowc[] = 'week'; } if ($month) { $rows[] = $this->formatBurnRow('Month To Date', $month); $rowc[] = 'month'; } $rows[] = $this->formatBurnRow('All Time', $period); $rowc[] = 'aggregate'; $rows = array_reverse($rows); $rowc = array_reverse($rowc); $table = new AphrontTableView($rows); $table->setRowClasses($rowc); $table->setHeaders(array('Period', 'Opened', 'Closed', 'Change')); $table->setColumnClasses(array('right wide', 'n', 'n', 'n')); if ($handle) { $header = "Task Burn Rate for Project " . $handle->renderLink(); $caption = "<p>NOTE: This table reflects tasks <em>currently</em> in " . "the project. If a task was opened in the past but added to " . "the project recently, it is counted on the day it was " . "opened, not the day it was categorized. If a task was part " . "of this project in the past but no longer is, it is not " . "counted at all.</p>"; } else { $header = "Task Burn Rate for All Tasks"; $caption = null; } $panel = new AphrontPanelView(); $panel->setHeader($header); $panel->setCaption($caption); $panel->appendChild($table); $tokens = array(); if ($handle) { $tokens = array($handle->getPHID() => $handle->getFullName()); } $filter = $this->renderReportFilters($tokens, $has_window = false); $id = celerity_generate_unique_node_id(); $chart = phutil_render_tag('div', array('id' => $id, 'style' => 'border: 1px solid #6f6f6f; ' . 'margin: 1em 2em; ' . 'height: 400px; '), ''); list($burn_x, $burn_y) = $this->buildSeries($data); require_celerity_resource('raphael-core'); require_celerity_resource('raphael-g'); require_celerity_resource('raphael-g-line'); Javelin::initBehavior('line-chart', array('hardpoint' => $id, 'x' => array($burn_x), 'y' => array($burn_y), 'xformat' => 'epoch')); return array($filter, $chart, $panel); }
public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $editable = $this->getAccountEditable(); $uri = $request->getRequestURI(); $uri->setQueryParams(array()); if ($editable) { $new = $request->getStr('new'); if ($new) { return $this->returnNewAddressResponse($uri, $new); } $delete = $request->getInt('delete'); if ($delete) { return $this->returnDeleteAddressResponse($uri, $delete); } } $verify = $request->getInt('verify'); if ($verify) { return $this->returnVerifyAddressResponse($uri, $verify); } $primary = $request->getInt('primary'); if ($primary) { return $this->returnPrimaryAddressResponse($uri, $primary); } $emails = id(new PhabricatorUserEmail())->loadAllWhere('userPHID = %s ORDER BY address', $user->getPHID()); $rowc = array(); $rows = array(); foreach ($emails as $email) { $button_verify = javelin_render_tag('a', array('class' => 'button small grey', 'href' => $uri->alter('verify', $email->getID()), 'sigil' => 'workflow'), 'Verify'); $button_make_primary = javelin_render_tag('a', array('class' => 'button small grey', 'href' => $uri->alter('primary', $email->getID()), 'sigil' => 'workflow'), 'Make Primary'); $button_remove = javelin_render_tag('a', array('class' => 'button small grey', 'href' => $uri->alter('delete', $email->getID()), 'sigil' => 'workflow'), 'Remove'); $button_primary = phutil_render_tag('a', array('class' => 'button small disabled'), 'Primary'); if (!$email->getIsVerified()) { $action = $button_verify; } else { if ($email->getIsPrimary()) { $action = $button_primary; } else { $action = $button_make_primary; } } if ($email->getIsPrimary()) { $remove = $button_primary; $rowc[] = 'highlighted'; } else { $remove = $button_remove; $rowc[] = null; } $rows[] = array(phutil_escape_html($email->getAddress()), $action, $remove); } $table = new AphrontTableView($rows); $table->setHeaders(array('Email', 'Status', 'Remove')); $table->setColumnClasses(array('wide', 'action', 'action')); $table->setRowClasses($rowc); $table->setColumnVisibility(array(true, true, $editable)); $view = new AphrontPanelView(); if ($editable) { $view->addButton(javelin_render_tag('a', array('href' => $uri->alter('new', 'true'), 'class' => 'green button', 'sigil' => 'workflow'), 'Add New Address')); } $view->setHeader('Email Addresses'); $view->appendChild($table); return $view; }