1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-09-20 09:18:48 +02:00

Show commits in /audit/

Summary:
The general idea here is to build a Differential-like dashboard which shows all
the things you need to audit and all the things that other people have raised
issues with, so you have a one-stop "what do I need to deal with?" interface.

  - Add problem commits to the "active" view of /audit/.
  - Add problem commits to homepage.
  - Add commit browsing interfaces to /audit/.
  - Add an "Audit" app button.

Test Plan: Looked at homepage, commit filters. Audited commits, verified state
changes reflected properly.

Reviewers: btrahan, jungejason

Reviewed By: btrahan

CC: aran, epriestley

Maniphest Tasks: T904

Differential Revision: https://secure.phabricator.com/D1712
This commit is contained in:
epriestley 2012-02-28 21:10:39 -08:00
parent 4117cdbdfb
commit f3549bb2d3
14 changed files with 646 additions and 82 deletions

View file

@ -445,6 +445,8 @@ phutil_register_library_map(array(
'PhabricatorAuditAddCommentController' => 'applications/audit/controller/addcomment', 'PhabricatorAuditAddCommentController' => 'applications/audit/controller/addcomment',
'PhabricatorAuditComment' => 'applications/audit/storage/auditcomment', 'PhabricatorAuditComment' => 'applications/audit/storage/auditcomment',
'PhabricatorAuditCommentEditor' => 'applications/audit/editor/comment', 'PhabricatorAuditCommentEditor' => 'applications/audit/editor/comment',
'PhabricatorAuditCommitListView' => 'applications/audit/view/commitlist',
'PhabricatorAuditCommitQuery' => 'applications/audit/query/commit',
'PhabricatorAuditCommitStatusConstants' => 'applications/audit/constants/commitstatus', 'PhabricatorAuditCommitStatusConstants' => 'applications/audit/constants/commitstatus',
'PhabricatorAuditController' => 'applications/audit/controller/base', 'PhabricatorAuditController' => 'applications/audit/controller/base',
'PhabricatorAuditDAO' => 'applications/audit/storage/base', 'PhabricatorAuditDAO' => 'applications/audit/storage/base',
@ -1240,6 +1242,7 @@ phutil_register_library_map(array(
'Phabricator404Controller' => 'PhabricatorController', 'Phabricator404Controller' => 'PhabricatorController',
'PhabricatorAuditAddCommentController' => 'PhabricatorAuditController', 'PhabricatorAuditAddCommentController' => 'PhabricatorAuditController',
'PhabricatorAuditComment' => 'PhabricatorAuditDAO', 'PhabricatorAuditComment' => 'PhabricatorAuditDAO',
'PhabricatorAuditCommitListView' => 'AphrontView',
'PhabricatorAuditController' => 'PhabricatorController', 'PhabricatorAuditController' => 'PhabricatorController',
'PhabricatorAuditDAO' => 'PhabricatorLiskDAO', 'PhabricatorAuditDAO' => 'PhabricatorLiskDAO',
'PhabricatorAuditEditController' => 'PhabricatorAuditController', 'PhabricatorAuditEditController' => 'PhabricatorAuditController',

View file

@ -56,6 +56,7 @@ final class PhabricatorAuditListController extends PhabricatorAuditController {
$message = 'Choose a project to view audits for.'; $message = 'Choose a project to view audits for.';
break; break;
case 'package': case 'package':
case 'packagecommits':
$title = 'Choose a Package'; $title = 'Choose a Package';
$message = 'Choose a package to view audits for.'; $message = 'Choose a package to view audits for.';
break; break;
@ -63,79 +64,14 @@ final class PhabricatorAuditListController extends PhabricatorAuditController {
} }
if (!$message) { if (!$message) {
$pager = new AphrontPagerView(); $nav->appendChild($this->buildViews($handle));
$pager->setURI($request->getRequestURI(), 'offset');
$query = new PhabricatorAuditQuery();
$query->setOffset($pager->getOffset());
$query->setLimit($pager->getPageSize() + 1);
$phids = null;
switch ($this->filter) {
case 'user':
case 'active':
$obj = id(new PhabricatorUser())->loadOneWhere(
'phid = %s',
$handle->getPHID());
if (!$obj) {
throw new Exception("Invalid user!");
}
$phids = PhabricatorAuditCommentEditor::loadAuditPHIDsForUser($obj);
break;
case 'project':
case 'package':
$phids = array($handle->getPHID());
break;
case 'all';
break;
default:
throw new Exception("Unknown filter!");
}
if ($phids) {
$query->withAuditorPHIDs($phids);
}
switch ($this->filter) {
case 'all':
case 'user':
case 'project':
case 'package':
switch ($this->filterStatus) {
case 'open':
$query->withStatus(PhabricatorAuditQuery::STATUS_OPEN);
break;
}
break;
case 'active':
$query->withStatus(PhabricatorAuditQuery::STATUS_OPEN);
break;
}
$audits = $query->execute();
$audits = $pager->sliceResults($audits);
$view = new PhabricatorAuditListView();
$view->setAudits($audits);
$phids = $view->getRequiredHandlePHIDs();
$handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
$view->setHandles($handles);
$panel = new AphrontPanelView();
$panel->appendChild($view);
$panel->setHeader('Audits');
} else { } else {
$panel = id(new AphrontErrorView()) $panel = id(new AphrontErrorView())
->setSeverity(AphrontErrorView::SEVERITY_NODATA) ->setSeverity(AphrontErrorView::SEVERITY_NODATA)
->setTitle($title) ->setTitle($title)
->appendChild($message); ->appendChild($message);
$pager = null;
}
$nav->appendChild($panel); $nav->appendChild($panel);
$nav->appendChild($pager); }
return $this->buildStandardPageResponse( return $this->buildStandardPageResponse(
$nav, $nav,
@ -149,12 +85,18 @@ final class PhabricatorAuditListController extends PhabricatorAuditController {
$nav->setBaseURI(new PhutilURI('/audit/view/')); $nav->setBaseURI(new PhutilURI('/audit/view/'));
$nav->addLabel('Active'); $nav->addLabel('Active');
$nav->addFilter('active', 'Need Attention'); $nav->addFilter('active', 'Need Attention');
$nav->addLabel('Audits'); $nav->addLabel('Audits');
$nav->addFilter('all', 'All'); $nav->addFilter('audits', 'All');
$nav->addFilter('user', 'By User'); $nav->addFilter('user', 'By User');
$nav->addFilter('project', 'By Project'); $nav->addFilter('project', 'By Project');
$nav->addFilter('package', 'By Package'); $nav->addFilter('package', 'By Package');
$nav->addLabel('Commits');
$nav->addFilter('commits', 'All');
$nav->addFilter('author', 'By User');
$nav->addFilter('packagecommits', 'By Package');
$this->filter = $nav->selectFilter($this->filter, 'active'); $this->filter = $nav->selectFilter($this->filter, 'active');
return $nav; return $nav;
@ -173,12 +115,14 @@ final class PhabricatorAuditListController extends PhabricatorAuditController {
$show_package = false; $show_package = false;
switch ($this->filter) { switch ($this->filter) {
case 'all': case 'audits':
case 'commits':
$show_status = true; $show_status = true;
break; break;
case 'active': case 'active':
$show_user = true; $show_user = true;
break; break;
case 'author':
case 'user': case 'user':
$show_user = true; $show_user = true;
$show_status = true; $show_status = true;
@ -188,6 +132,7 @@ final class PhabricatorAuditListController extends PhabricatorAuditController {
$show_status = true; $show_status = true;
break; break;
case 'package': case 'package':
case 'packagecommits':
$show_package = true; $show_package = true;
$show_status = true; $show_status = true;
break; break;
@ -251,6 +196,7 @@ final class PhabricatorAuditListController extends PhabricatorAuditController {
switch ($this->filter) { switch ($this->filter) {
case 'user': case 'user':
case 'active': case 'active':
case 'author':
$default = $request->getUser()->getPHID(); $default = $request->getUser()->getPHID();
break; break;
} }
@ -272,11 +218,13 @@ final class PhabricatorAuditListController extends PhabricatorAuditController {
switch ($this->filter) { switch ($this->filter) {
case 'active': case 'active':
case 'user': case 'user':
case 'author':
if ($handle->getType() !== PhabricatorPHIDConstants::PHID_TYPE_USER) { if ($handle->getType() !== PhabricatorPHIDConstants::PHID_TYPE_USER) {
throw new Exception("PHID must be a user PHID!"); throw new Exception("PHID must be a user PHID!");
} }
break; break;
case 'package': case 'package':
case 'packagecommits':
if ($handle->getType() !== PhabricatorPHIDConstants::PHID_TYPE_OPKG) { if ($handle->getType() !== PhabricatorPHIDConstants::PHID_TYPE_OPKG) {
throw new Exception("PHID must be a package PHID!"); throw new Exception("PHID must be a package PHID!");
} }
@ -286,11 +234,220 @@ final class PhabricatorAuditListController extends PhabricatorAuditController {
throw new Exception("PHID must be a project PHID!"); throw new Exception("PHID must be a project PHID!");
} }
break; break;
case 'all': case 'audits':
case 'commits':
break; break;
default: default:
throw new Exception("Unknown filter '{$this->filter}'!"); throw new Exception("Unknown filter '{$this->filter}'!");
} }
} }
private function buildViews(PhabricatorObjectHandle $handle = null) {
$views = array();
switch ($this->filter) {
case 'active':
$views[] = $this->buildAuditView($handle);
$views[] = $this->buildCommitView($handle);
break;
case 'audits':
case 'user':
case 'package':
case 'project':
$views[] = $this->buildAuditView($handle);
break;
case 'commits':
case 'packagecommits':
case 'author':
$views[] = $this->buildCommitView($handle);
break;
}
return $views;
}
private function buildAuditView(PhabricatorObjectHandle $handle = null) {
$request = $this->getRequest();
$pager = new AphrontPagerView();
$pager->setURI($request->getRequestURI(), 'offset');
$query = new PhabricatorAuditQuery();
if ($this->filter != 'active') {
$query->setOffset($pager->getOffset());
$query->setLimit($pager->getPageSize() + 1);
}
$phids = null;
switch ($this->filter) {
case 'user':
case 'active':
$obj = id(new PhabricatorUser())->loadOneWhere(
'phid = %s',
$handle->getPHID());
if (!$obj) {
throw new Exception("Invalid user!");
}
$phids = PhabricatorAuditCommentEditor::loadAuditPHIDsForUser($obj);
break;
case 'project':
case 'package':
$phids = array($handle->getPHID());
break;
case 'audits';
break;
default:
throw new Exception("Unknown filter!");
}
if ($phids) {
$query->withAuditorPHIDs($phids);
}
switch ($this->filter) {
case 'audits':
case 'user':
case 'project':
case 'package':
switch ($this->filterStatus) {
case 'open':
$query->withStatus(PhabricatorAuditQuery::STATUS_OPEN);
break;
}
break;
case 'active':
$query->withStatus(PhabricatorAuditQuery::STATUS_OPEN);
break;
}
if ($handle) {
$handle_name = phutil_escape_html($handle->getName());
} else {
$handle_name = null;
}
switch ($this->filter) {
case 'active':
$header = 'Required Audits';
$nodata = 'No commits require your audit.';
break;
case 'user':
$header = "Audits for {$handle_name}";
$nodata = "No matching audits by {$handle_name}.";
break;
case 'audits':
$header = "Audits";
$nodata = "No matching audits.";
break;
case 'project':
$header = "Audits in Project '{$handle_name}'";
$nodata = "No matching audits in project '{$handle_name}'.";
break;
case 'package':
$header = "Audits for Package '{$handle_name}'";
$nodata = "No matching audits in package '{$handle_name}'.";
break;
}
$audits = $query->execute();
$audits = $pager->sliceResults($audits);
$view = new PhabricatorAuditListView();
$view->setAudits($audits);
$view->setNoDataString($nodata);
$phids = $view->getRequiredHandlePHIDs();
$handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
$view->setHandles($handles);
$panel = new AphrontPanelView();
$panel->setHeader($header);
$panel->appendChild($view);
$panel->appendChild($pager);
return $panel;
}
private function buildCommitView(PhabricatorObjectHandle $handle = null) {
$request = $this->getRequest();
$pager = new AphrontPagerView();
$pager->setURI($request->getRequestURI(), 'offset');
$query = new PhabricatorAuditCommitQuery();
$query->needCommitData(true);
if ($this->filter != 'active') {
$query->setOffset($pager->getOffset());
$query->setLimit($pager->getPageSize() + 1);
}
switch ($this->filter) {
case 'active':
case 'author':
$query->withAuthorPHIDs(array($handle->getPHID()));
break;
case 'packagecommits':
$query->withPackagePHIDs(array($handle->getPHID()));
break;
}
switch ($this->filter) {
case 'active':
$query->withStatus(PhabricatorAuditQuery::STATUS_OPEN);
break;
case 'author':
case 'packagecommits':
switch ($this->filterStatus) {
case 'open':
$query->withStatus(PhabricatorAuditQuery::STATUS_OPEN);
break;
}
break;
}
if ($handle) {
$handle_name = phutil_escape_html($handle->getName());
} else {
$handle_name = null;
}
switch ($this->filter) {
case 'active':
$header = 'Problem Commits';
$nodata = 'None of your commits have open concerns.';
break;
case 'author':
$header = "Commits by {$handle_name}";
$nodata = "No matching commits by {$handle_name}.";
break;
case 'commits':
$header = "Commits";
$nodata = "No matching commits.";
break;
case 'packagecommits':
$header = "Commits in Package '{$handle_name}'";
$nodata = "No matching commits in package '{$handle_name}'.";
break;
}
$commits = $query->execute();
$commits = $pager->sliceResults($commits);
$view = new PhabricatorAuditCommitListView();
$view->setUser($request->getUser());
$view->setCommits($commits);
$view->setNoDataString($nodata);
$phids = $view->getRequiredHandlePHIDs();
$handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
$view->setHandles($handles);
$panel = new AphrontPanelView();
$panel->setHeader($header);
$panel->appendChild($view);
$panel->appendChild($pager);
return $panel;
}
} }

View file

@ -10,6 +10,8 @@ phutil_require_module('phabricator', 'aphront/response/redirect');
phutil_require_module('phabricator', 'applications/audit/controller/base'); phutil_require_module('phabricator', 'applications/audit/controller/base');
phutil_require_module('phabricator', 'applications/audit/editor/comment'); phutil_require_module('phabricator', 'applications/audit/editor/comment');
phutil_require_module('phabricator', 'applications/audit/query/audit'); phutil_require_module('phabricator', 'applications/audit/query/audit');
phutil_require_module('phabricator', 'applications/audit/query/commit');
phutil_require_module('phabricator', 'applications/audit/view/commitlist');
phutil_require_module('phabricator', 'applications/audit/view/list'); phutil_require_module('phabricator', 'applications/audit/view/list');
phutil_require_module('phabricator', 'applications/people/storage/user'); phutil_require_module('phabricator', 'applications/people/storage/user');
phutil_require_module('phabricator', 'applications/phid/constants'); phutil_require_module('phabricator', 'applications/phid/constants');
@ -24,6 +26,7 @@ phutil_require_module('phabricator', 'view/layout/listfilter');
phutil_require_module('phabricator', 'view/layout/panel'); phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phabricator', 'view/layout/sidenavfilter'); phutil_require_module('phabricator', 'view/layout/sidenavfilter');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'parser/uri'); phutil_require_module('phutil', 'parser/uri');
phutil_require_module('phutil', 'utils'); phutil_require_module('phutil', 'utils');

View file

@ -0,0 +1,177 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class PhabricatorAuditCommitQuery {
private $offset;
private $limit;
private $authorPHIDs;
private $packagePHIDs;
private $packageConstraint;
private $needCommitData;
private $status = 'status-any';
const STATUS_ANY = 'status-any';
const STATUS_OPEN = 'status-open';
public function withAuthorPHIDs(array $author_phids) {
$this->authorPHIDs = $author_phids;
return $this;
}
public function withPackagePHIDs(array $phids) {
$this->packagePHIDs = $phids;
return $this;
}
public function withStatus($status) {
$this->status = $status;
return $this;
}
public function needCommitData($need) {
$this->needCommitData = $need;
return $this;
}
public function setOffset($offset) {
$this->offset = $offset;
return $this;
}
public function setLimit($limit) {
$this->limit = $limit;
return $this;
}
public function execute() {
if ($this->packagePHIDs) {
// TODO: This is an odd, awkward query plan because these rows aren't
// on the same database as the commits. Once they're migrated we can
// resolve this via JOIN.
$table = new PhabricatorOwnersPackageCommitRelationship();
$conn_r = $table->establishConnection('r');
$phids = queryfx_all(
$conn_r,
'SELECT DISTINCT commitPHID FROM %T WHERE packagePHID IN (%Ls)
ORDER BY id DESC %Q',
$table->getTableName(),
$this->packagePHIDs,
$this->buildLimitClause($conn_r));
$this->packageConstraint = ipull($phids, 'commitPHID');
$this->limit = null;
$this->offset = null;
}
$table = new PhabricatorRepositoryCommit();
$conn_r = $table->establishConnection('r');
$where = $this->buildWhereClause($conn_r);
$order = $this->buildOrderClause($conn_r);
$limit = $this->buildLimitClause($conn_r);
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$where,
$order,
$limit);
$commits = $table->loadAllFromArray($data);
if ($this->needCommitData && $commits) {
$data = id(new PhabricatorRepositoryCommitData())->loadAllWhere(
'commitID in (%Ld)',
mpull($commits, 'getID'));
$data = mpull($data, null, 'getCommitID');
foreach ($commits as $commit) {
if (idx($data, $commit->getID())) {
$commit->attachCommitData($data[$commit->getID()]);
} else {
$commit->attachCommitData(new PhabricatorRepositoryCommitData());
}
}
}
return $commits;
}
private function buildOrderClause($conn_r) {
return 'ORDER BY epoch DESC';
}
private function buildWhereClause($conn_r) {
$where = array();
if ($this->authorPHIDs) {
$where[] = qsprintf(
$conn_r,
'authorPHID IN (%Ls)',
$this->authorPHIDs);
}
if ($this->packageConstraint !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->packageConstraint);
}
$status = $this->status;
switch ($status) {
case self::STATUS_OPEN:
$where[] = qsprintf(
$conn_r,
'auditStatus = %s',
PhabricatorAuditCommitStatusConstants::CONCERN_RAISED);
break;
case self::STATUS_ANY:
break;
default:
throw new Exception("Unknown status '{$status}'!");
}
if ($where) {
$where = 'WHERE ('.implode(') AND (', $where).')';
} else {
$where = '';
}
return $where;
}
private function buildLimitClause($conn_r) {
if ($this->limit && $this->offset) {
return qsprintf($conn_r, 'LIMIT %d, %d', $this->offset, $this->limit);
} else if ($this->limit) {
return qsprintf($conn_r, 'LIMIT %d', $this->limit);
} else if ($this->offset) {
return qsprintf($conn_r, 'LIMIT %d, %d', $this->offset, PHP_INT_MAX);
} else {
return '';
}
}
}

View file

@ -0,0 +1,19 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/audit/constants/commitstatus');
phutil_require_module('phabricator', 'applications/owners/storage/packagecommitrelationship');
phutil_require_module('phabricator', 'applications/repository/storage/commit');
phutil_require_module('phabricator', 'applications/repository/storage/commitdata');
phutil_require_module('phabricator', 'storage/qsprintf');
phutil_require_module('phabricator', 'storage/queryfx');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorAuditCommitQuery.php');

View file

@ -0,0 +1,113 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class PhabricatorAuditCommitListView extends AphrontView {
private $user;
private $commits;
private $handles;
private $noDataString;
public function setUser(PhabricatorUser $user) {
$this->user = $user;
return $this;
}
public function setNoDataString($no_data_string) {
$this->noDataString = $no_data_string;
return $this;
}
public function setCommits(array $commits) {
$this->commits = $commits;
return $this;
}
public function setHandles(array $handles) {
$this->handles = $handles;
return $this;
}
public function setAuthorityPHIDs(array $phids) {
$this->authorityPHIDs = $phids;
return $this;
}
public function getRequiredHandlePHIDs() {
$phids = array();
foreach ($this->commits as $commit) {
if ($commit->getAuthorPHID()) {
$phids[$commit->getAuthorPHID()] = true;
}
$phids[$commit->getPHID()] = true;
}
return array_keys($phids);
}
private function getHandle($phid) {
$handle = idx($this->handles, $phid);
if (!$handle) {
throw new Exception("No handle for '{$phid}'!");
}
return $handle;
}
public function render() {
$rows = array();
foreach ($this->commits as $commit) {
$commit_name = $this->getHandle($commit->getPHID())->renderLink();
$author_name = null;
if ($commit->getAuthorPHID()) {
$author_name = $this->getHandle($commit->getAuthorPHID())->renderLink();
}
$rows[] = array(
$commit_name,
$author_name,
phutil_escape_html($commit->getCommitData()->getSummary()),
PhabricatorAuditCommitStatusConstants::getStatusName(
$commit->getAuditStatus()),
phabricator_datetime($commit->getEpoch(), $this->user),
);
}
$table = new AphrontTableView($rows);
$table->setHeaders(
array(
'Commit',
'Author',
'Summary',
'Audit Status',
'Date',
));
$table->setColumnClasses(
array(
'n',
'',
'wide',
'',
'',
));
if ($this->noDataString) {
$table->setNoDataString($this->noDataString);
}
return $table->render();
}
}

View file

@ -0,0 +1,18 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/audit/constants/commitstatus');
phutil_require_module('phabricator', 'view/base');
phutil_require_module('phabricator', 'view/control/table');
phutil_require_module('phabricator', 'view/utils');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorAuditCommitListView.php');

View file

@ -21,6 +21,7 @@ final class PhabricatorAuditListView extends AphrontView {
private $audits; private $audits;
private $handles; private $handles;
private $authorityPHIDs = array(); private $authorityPHIDs = array();
private $noDataString;
public function setAudits(array $audits) { public function setAudits(array $audits) {
$this->audits = $audits; $this->audits = $audits;
@ -37,6 +38,15 @@ final class PhabricatorAuditListView extends AphrontView {
return $this; return $this;
} }
public function setNoDataString($no_data_string) {
$this->noDataString = $no_data_string;
return $this;
}
public function getNoDataString() {
return $this->noDataString;
}
public function getRequiredHandlePHIDs() { public function getRequiredHandlePHIDs() {
$phids = array(); $phids = array();
foreach ($this->audits as $audit) { foreach ($this->audits as $audit) {
@ -112,6 +122,10 @@ final class PhabricatorAuditListView extends AphrontView {
)); ));
$table->setRowClasses($rowc); $table->setRowClasses($rowc);
if ($this->noDataString) {
$table->setNoDataString($this->noDataString);
}
return $table->render(); return $table->render();
} }

View file

@ -78,6 +78,7 @@ class PhabricatorDirectoryMainController
$revision_panel = $this->buildRevisionPanel(); $revision_panel = $this->buildRevisionPanel();
$app_panel = $this->buildAppPanel(); $app_panel = $this->buildAppPanel();
$audit_panel = $this->buildAuditPanel(); $audit_panel = $this->buildAuditPanel();
$commit_panel = $this->buildCommitPanel();
$content = array( $content = array(
$app_panel, $app_panel,
@ -87,6 +88,7 @@ class PhabricatorDirectoryMainController
$revision_panel, $revision_panel,
$tasks_panel, $tasks_panel,
$audit_panel, $audit_panel,
$commit_panel,
); );
$nav->appendChild($content); $nav->appendChild($content);
@ -577,6 +579,11 @@ class PhabricatorDirectoryMainController
'/diffusion/', '/diffusion/',
'diffusion'); 'diffusion');
$nav_buttons[] = array(
'Audit Code',
'/audit/',
'audit');
$view = new AphrontNullView(); $view = new AphrontNullView();
$view->appendChild('<div class="phabricator-app-buttons">'); $view->appendChild('<div class="phabricator-app-buttons">');
foreach ($nav_buttons as $info) { foreach ($nav_buttons as $info) {
@ -638,13 +645,9 @@ class PhabricatorDirectoryMainController
$audits = $query->execute(); $audits = $query->execute();
if (!$audits) { if (!$audits) {
$panel = new AphrontMiniPanelView(); return $this->renderMinipanel(
$panel->appendChild( 'No Audits',
'<p>'. 'No commits are waiting for you to audit them.');
'<strong>No Audits:</strong> '.
'No commits are waiting for you to audit them.'.
'</p>');
return $panel;
} }
$view = new PhabricatorAuditListView(); $view = new PhabricatorAuditListView();
@ -670,4 +673,48 @@ class PhabricatorDirectoryMainController
return $panel; return $panel;
} }
public function buildCommitPanel() {
$request = $this->getRequest();
$user = $request->getUser();
$phids = array($user->getPHID());
$query = new PhabricatorAuditCommitQuery();
$query->withAuthorPHIDs($phids);
$query->withStatus(PhabricatorAuditQuery::STATUS_OPEN);
$query->needCommitData(true);
$query->setLimit(10);
$commits = $query->execute();
if (!$commits) {
return $this->renderMinipanel(
'No Problem Commits',
'No one has raised concerns with your commits.');
}
$view = new PhabricatorAuditCommitListView();
$view->setCommits($commits);
$view->setUser($user);
$phids = $view->getRequiredHandlePHIDs();
$handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
$view->setHandles($handles);
$panel = new AphrontPanelView();
$panel->setHeader('Problem Commits');
$panel->setCaption('Commits which auditors have raised concerns about.');
$panel->appendChild($view);
$panel->addButton(
phutil_render_tag(
'a',
array(
'href' => '/audit/',
'class' => 'button grey',
),
"View Problem Commits \xC2\xBB"));
return $panel;
}
} }

View file

@ -9,6 +9,8 @@
phutil_require_module('phabricator', 'aphront/response/redirect'); phutil_require_module('phabricator', 'aphront/response/redirect');
phutil_require_module('phabricator', 'applications/audit/editor/comment'); phutil_require_module('phabricator', 'applications/audit/editor/comment');
phutil_require_module('phabricator', 'applications/audit/query/audit'); phutil_require_module('phabricator', 'applications/audit/query/audit');
phutil_require_module('phabricator', 'applications/audit/query/commit');
phutil_require_module('phabricator', 'applications/audit/view/commitlist');
phutil_require_module('phabricator', 'applications/audit/view/list'); phutil_require_module('phabricator', 'applications/audit/view/list');
phutil_require_module('phabricator', 'applications/differential/query/revision'); phutil_require_module('phabricator', 'applications/differential/query/revision');
phutil_require_module('phabricator', 'applications/differential/view/revisionlist'); phutil_require_module('phabricator', 'applications/differential/view/revisionlist');

View file

@ -218,6 +218,7 @@ class PhabricatorObjectHandle {
public function getLinkName() { public function getLinkName() {
switch ($this->getType()) { switch ($this->getType()) {
case PhabricatorPHIDConstants::PHID_TYPE_USER: case PhabricatorPHIDConstants::PHID_TYPE_USER:
case PhabricatorPHIDConstants::PHID_TYPE_CMIT:
$name = $this->getName(); $name = $this->getName();
break; break;
default: default:

View file

@ -265,8 +265,14 @@ class PhabricatorObjectHandleData {
// we don't have have info about the repository anymore. // we don't have have info about the repository anymore.
if ($repository) { if ($repository) {
$vcs = $repository->getVersionControlSystem(); $vcs = $repository->getVersionControlSystem();
if ($vcs == PhabricatorRepositoryType::REPOSITORY_TYPE_GIT) {
$short_identifier = substr($commit_identifier, 0, 16); $type_git = PhabricatorRepositoryType::REPOSITORY_TYPE_GIT;
$type_hg = PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL;
$is_git = ($vcs == $type_git);
$is_hg = ($vcs == $type_hg);
if ($is_git || $is_hg) {
$short_identifier = substr($commit_identifier, 0, 12);
} else { } else {
$short_identifier = $commit_identifier; $short_identifier = $commit_identifier;
} }

View file

@ -97,3 +97,7 @@ a.phabricator-button-caption:visited {
.icon-diffusion { .icon-diffusion {
background-position: 0 -300px; background-position: 0 -300px;
} }
.icon-audit {
background-position: 0 -350px;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB