mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-22 21:40:55 +01:00
Use ApplicationSearch in projects
Summary: Ref T2715. I stripped a bunch of stuff from the list since it was buggy, slow, or both. Some day, we'll rebuild it. Test Plan: {F51128} Reviewers: btrahan, chad Reviewed By: btrahan CC: aran Maniphest Tasks: T2715 Differential Revision: https://secure.phabricator.com/D6525
This commit is contained in:
parent
7cbe82d777
commit
b574b3ff8e
6 changed files with 161 additions and 150 deletions
|
@ -1402,6 +1402,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProjectProfileController' => 'applications/project/controller/PhabricatorProjectProfileController.php',
|
||||
'PhabricatorProjectProfileEditController' => 'applications/project/controller/PhabricatorProjectProfileEditController.php',
|
||||
'PhabricatorProjectQuery' => 'applications/project/query/PhabricatorProjectQuery.php',
|
||||
'PhabricatorProjectSearchEngine' => 'applications/project/query/PhabricatorProjectSearchEngine.php',
|
||||
'PhabricatorProjectStatus' => 'applications/project/constants/PhabricatorProjectStatus.php',
|
||||
'PhabricatorProjectTestDataGenerator' => 'applications/project/lipsum/PhabricatorProjectTestDataGenerator.php',
|
||||
'PhabricatorProjectTransaction' => 'applications/project/storage/PhabricatorProjectTransaction.php',
|
||||
|
@ -3394,13 +3395,18 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProjectDAO' => 'PhabricatorLiskDAO',
|
||||
'PhabricatorProjectEditor' => 'PhabricatorEditor',
|
||||
'PhabricatorProjectEditorTestCase' => 'PhabricatorTestCase',
|
||||
'PhabricatorProjectListController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectListController' =>
|
||||
array(
|
||||
0 => 'PhabricatorProjectController',
|
||||
1 => 'PhabricatorApplicationSearchResultsControllerInterface',
|
||||
),
|
||||
'PhabricatorProjectMembersEditController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectNameCollisionException' => 'Exception',
|
||||
'PhabricatorProjectProfile' => 'PhabricatorProjectDAO',
|
||||
'PhabricatorProjectProfileController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectProfileEditController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorProjectSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhabricatorProjectTestDataGenerator' => 'PhabricatorTestDataGenerator',
|
||||
'PhabricatorProjectTransaction' => 'PhabricatorProjectDAO',
|
||||
'PhabricatorProjectTransactionType' => 'PhabricatorProjectConstants',
|
||||
|
|
|
@ -35,7 +35,7 @@ final class PhabricatorApplicationProject extends PhabricatorApplication {
|
|||
public function getRoutes() {
|
||||
return array(
|
||||
'/project/' => array(
|
||||
'' => 'PhabricatorProjectListController',
|
||||
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhabricatorProjectListController',
|
||||
'filter/(?P<filter>[^/]+)/' => 'PhabricatorProjectListController',
|
||||
'edit/(?P<id>[1-9]\d*)/' => 'PhabricatorProjectProfileEditController',
|
||||
'members/(?P<id>[1-9]\d*)/'
|
||||
|
|
|
@ -14,15 +14,6 @@ final class PhabricatorProjectStatus {
|
|||
return idx($map, coalesce($status, '?'), pht('Unknown'));
|
||||
}
|
||||
|
||||
public static function getIconForStatus($status) {
|
||||
$map = array(
|
||||
self::STATUS_ACTIVE => 'check',
|
||||
self::STATUS_ARCHIVED => 'disable',
|
||||
);
|
||||
|
||||
return idx($map, $status);
|
||||
}
|
||||
|
||||
public static function getStatusMap() {
|
||||
return array(
|
||||
self::STATUS_ACTIVE => pht('Active'),
|
||||
|
|
|
@ -2,23 +2,22 @@
|
|||
|
||||
abstract class PhabricatorProjectController extends PhabricatorController {
|
||||
|
||||
public function buildSideNavView($filter = null, $for_app = false) {
|
||||
public function buildSideNavView($for_app = false) {
|
||||
$user = $this->getRequest()->getUser();
|
||||
|
||||
$nav = new AphrontSideNavFilterView();
|
||||
$nav
|
||||
->setBaseURI(new PhutilURI('/project/filter/'))
|
||||
->addLabel(pht('User'))
|
||||
->addFilter('active', pht('Active'))
|
||||
->addLabel(pht('All'))
|
||||
->addFilter('all', pht('All Projects'))
|
||||
->addFilter('allactive', pht('Active Projects'))
|
||||
->selectFilter($filter, 'active');
|
||||
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
|
||||
|
||||
if ($for_app) {
|
||||
$nav->addFilter('create/', pht('Create Project'));
|
||||
$nav->addFilter('create', pht('Create Project'));
|
||||
}
|
||||
|
||||
id(new PhabricatorProjectSearchEngine())
|
||||
->setViewer($user)
|
||||
->addNavigationItems($nav->getMenu());
|
||||
|
||||
$nav->selectFilter(null);
|
||||
|
||||
return $nav;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,151 +1,54 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorProjectListController
|
||||
extends PhabricatorProjectController {
|
||||
extends PhabricatorProjectController
|
||||
implements PhabricatorApplicationSearchResultsControllerInterface {
|
||||
|
||||
private $filter;
|
||||
private $queryKey;
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->filter = idx($data, 'filter');
|
||||
$this->queryKey = idx($data, 'queryKey');
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$controller = id(new PhabricatorApplicationSearchController($request))
|
||||
->setQueryKey($this->queryKey)
|
||||
->setSearchEngine(new PhabricatorProjectSearchEngine())
|
||||
->setNavigation($this->buildSideNavView());
|
||||
|
||||
$nav = $this->buildSideNavView($this->filter);
|
||||
$this->filter = $nav->selectFilter($this->filter, 'active');
|
||||
|
||||
$pager = new AphrontPagerView();
|
||||
$pager->setPageSize(250);
|
||||
$pager->setURI($request->getRequestURI(), 'page');
|
||||
$pager->setOffset($request->getInt('page'));
|
||||
|
||||
$query = new PhabricatorProjectQuery();
|
||||
$query->setViewer($request->getUser());
|
||||
$query->needMembers(true);
|
||||
|
||||
$view_phid = $request->getUser()->getPHID();
|
||||
|
||||
switch ($this->filter) {
|
||||
case 'active':
|
||||
$table_header = pht('Your Projects');
|
||||
$query->withMemberPHIDs(array($view_phid));
|
||||
$query->withStatus(PhabricatorProjectQuery::STATUS_ACTIVE);
|
||||
break;
|
||||
case 'allactive':
|
||||
$table_header = pht('Active Projects');
|
||||
$query->withStatus(PhabricatorProjectQuery::STATUS_ACTIVE);
|
||||
break;
|
||||
case 'all':
|
||||
$table_header = pht('All Projects');
|
||||
$query->withStatus(PhabricatorProjectQuery::STATUS_ANY);
|
||||
break;
|
||||
return $this->delegateToController($controller);
|
||||
}
|
||||
|
||||
$projects = $query->executeWithOffsetPager($pager);
|
||||
|
||||
$project_phids = mpull($projects, 'getPHID');
|
||||
|
||||
$profiles = array();
|
||||
if ($projects) {
|
||||
$profiles = id(new PhabricatorProjectProfile())->loadAllWhere(
|
||||
'projectPHID in (%Ls)',
|
||||
$project_phids);
|
||||
$profiles = mpull($profiles, null, 'getProjectPHID');
|
||||
}
|
||||
|
||||
$tasks = array();
|
||||
$groups = array();
|
||||
if ($project_phids) {
|
||||
$query = id(new ManiphestTaskQuery())
|
||||
->withAnyProjects($project_phids)
|
||||
->withStatus(ManiphestTaskQuery::STATUS_OPEN)
|
||||
->setLimit(PHP_INT_MAX);
|
||||
|
||||
$tasks = $query->execute();
|
||||
foreach ($tasks as $task) {
|
||||
foreach ($task->getProjectPHIDs() as $phid) {
|
||||
$groups[$phid][] = $task;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$rows = array();
|
||||
foreach ($projects as $project) {
|
||||
$phid = $project->getPHID();
|
||||
|
||||
$profile = idx($profiles, $phid);
|
||||
$members = $project->getMemberPHIDs();
|
||||
|
||||
$group = idx($groups, $phid, array());
|
||||
$task_count = count($group);
|
||||
$population = count($members);
|
||||
|
||||
if ($profile) {
|
||||
$blurb = $profile->getBlurb();
|
||||
$blurb = phutil_utf8_shorten($blurb, 64);
|
||||
} else {
|
||||
$blurb = null;
|
||||
}
|
||||
|
||||
$tasks_href = pht('%d Open Task(s)', $task_count);
|
||||
|
||||
$rows[] = array(
|
||||
$project->getName(),
|
||||
'/project/view/'.$project->getID().'/',
|
||||
PhabricatorProjectStatus::getNameForStatus($project->getStatus()),
|
||||
PhabricatorProjectStatus::getIconForStatus($project->getStatus()),
|
||||
$blurb,
|
||||
pht('%d Member(s)', $population),
|
||||
phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => '/maniphest/view/all/?projects='.$phid,
|
||||
),
|
||||
$tasks_href),
|
||||
'/project/edit/'.$project->getID().'/',
|
||||
);
|
||||
}
|
||||
public function renderResultsList(
|
||||
array $projects,
|
||||
PhabricatorSavedQuery $query) {
|
||||
assert_instances_of($projects, 'PhabricatorProject');
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
|
||||
$list = new PhabricatorObjectItemListView();
|
||||
$list->setStackable(true);
|
||||
foreach ($rows as $row) {
|
||||
$list->setUser($viewer);
|
||||
foreach ($projects as $project) {
|
||||
$id = $project->getID();
|
||||
|
||||
$item = id(new PhabricatorObjectItemView())
|
||||
->setHeader($row[0])
|
||||
->setHref($row[1])
|
||||
->addIcon($row[3], $row[2])
|
||||
->addIcon('edit', pht('Edit Project'), array('href' => $row[7]));
|
||||
if ($row[4]) {
|
||||
$item->addAttribute($row[4]);
|
||||
->setHeader($project->getName())
|
||||
->setHref($this->getApplicationURI("view/{$id}/"));
|
||||
|
||||
if ($project->getStatus() == PhabricatorProjectStatus::STATUS_ARCHIVED) {
|
||||
$item->addIcon('delete-grey', pht('Archived'));
|
||||
$item->setDisabled(true);
|
||||
}
|
||||
$item->addAttribute($row[5]);
|
||||
$item->addAttribute($row[6]);
|
||||
|
||||
|
||||
$list->addItem($item);
|
||||
}
|
||||
|
||||
$nav->appendChild(
|
||||
array(
|
||||
$list,
|
||||
$pager,
|
||||
));
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs($this->buildSideNavView());
|
||||
$crumbs->addCrumb(
|
||||
id(new PhabricatorCrumbView())
|
||||
->setName($table_header)
|
||||
->setHref($this->getApplicationURI()));
|
||||
$nav->setCrumbs($crumbs);
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
$nav,
|
||||
array(
|
||||
'title' => pht('Projects'),
|
||||
'device' => true,
|
||||
'dust' => true,
|
||||
));
|
||||
return $list;
|
||||
}
|
||||
|
||||
public function buildApplicationMenu() {
|
||||
return $this->buildSideNavView(null, true)->getMenu();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorProjectSearchEngine
|
||||
extends PhabricatorApplicationSearchEngine {
|
||||
|
||||
public function buildSavedQueryFromRequest(AphrontRequest $request) {
|
||||
$saved = new PhabricatorSavedQuery();
|
||||
|
||||
$saved->setParameter('memberPHIDs', $request->getArr('memberPHIDs'));
|
||||
$saved->setParameter('status', $request->getStr('status'));
|
||||
|
||||
return $saved;
|
||||
}
|
||||
|
||||
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
|
||||
$query = id(new PhabricatorProjectQuery());
|
||||
|
||||
$member_phids = $saved->getParameter('memberPHIDs', array());
|
||||
if ($member_phids && is_array($member_phids)) {
|
||||
$query->withMemberPHIDs($member_phids);
|
||||
}
|
||||
|
||||
$status = $saved->getParameter('status');
|
||||
$status = idx($this->getStatusValues(), $status);
|
||||
if ($status) {
|
||||
$query->withStatus($status);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function buildSearchForm(
|
||||
AphrontFormView $form,
|
||||
PhabricatorSavedQuery $saved_query) {
|
||||
|
||||
$phids = $saved_query->getParameter('memberPHIDs', array());
|
||||
$handles = id(new PhabricatorObjectHandleData($phids))
|
||||
->setViewer($this->requireViewer())
|
||||
->loadHandles();
|
||||
$member_tokens = mpull($handles, 'getFullName', 'getPHID');
|
||||
|
||||
$status = $saved_query->getParameter('status');
|
||||
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setDatasource('/typeahead/common/users/')
|
||||
->setName('memberPHIDs')
|
||||
->setLabel(pht('Members'))
|
||||
->setValue($member_tokens))
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel(pht('Status'))
|
||||
->setName('status')
|
||||
->setOptions($this->getStatusOptions())
|
||||
->setValue($status));
|
||||
}
|
||||
|
||||
protected function getURI($path) {
|
||||
return '/project/'.$path;
|
||||
}
|
||||
|
||||
public function getBuiltinQueryNames() {
|
||||
$names = array();
|
||||
|
||||
if ($this->requireViewer()->isLoggedIn()) {
|
||||
$names['joined'] = pht('Joined');
|
||||
}
|
||||
|
||||
$names['active'] = pht('Active');
|
||||
$names['all'] = pht('All');
|
||||
|
||||
return $names;
|
||||
}
|
||||
|
||||
public function buildSavedQueryFromBuiltin($query_key) {
|
||||
|
||||
$query = $this->newSavedQuery();
|
||||
$query->setQueryKey($query_key);
|
||||
|
||||
$viewer_phid = $this->requireViewer()->getPHID();
|
||||
|
||||
switch ($query_key) {
|
||||
case 'all':
|
||||
return $query;
|
||||
case 'active':
|
||||
return $query
|
||||
->setParameter('status', 'active');
|
||||
case 'joined':
|
||||
return $query
|
||||
->setParameter('memberPHIDs', array($viewer_phid))
|
||||
->setParameter('status', 'active');
|
||||
}
|
||||
|
||||
return parent::buildSavedQueryFromBuiltin($query_key);
|
||||
}
|
||||
|
||||
private function getStatusOptions() {
|
||||
return array(
|
||||
'active' => pht('Show Only Active Projects'),
|
||||
'all' => pht('Show All Projects'),
|
||||
);
|
||||
}
|
||||
|
||||
private function getStatusValues() {
|
||||
return array(
|
||||
'active' => PhabricatorProjectQuery::STATUS_ACTIVE,
|
||||
'all' => PhabricatorProjectQuery::STATUS_ANY,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue