1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-21 13:00:56 +01:00

Use ApplicationSearch in Releeph project list

Summary: Ref T3092. Convert Releeph project list to ApplicationSearch.

Test Plan: {F50333}

Reviewers: btrahan, edward

Reviewed By: edward

CC: aran

Maniphest Tasks: T3092

Differential Revision: https://secure.phabricator.com/D6474
This commit is contained in:
epriestley 2013-07-21 08:44:53 -07:00
parent 904a24c1df
commit 215da7728f
7 changed files with 213 additions and 303 deletions

View file

@ -1868,7 +1868,6 @@ phutil_register_library_map(array(
'PonderVoteSaveController' => 'applications/ponder/controller/PonderVoteSaveController.php',
'ProjectRemarkupRule' => 'applications/project/remarkup/ProjectRemarkupRule.php',
'QueryFormattingTestCase' => 'infrastructure/storage/__tests__/QueryFormattingTestCase.php',
'ReleephActiveProjectListView' => 'applications/releeph/view/project/list/ReleephActiveProjectListView.php',
'ReleephAuthorFieldSpecification' => 'applications/releeph/field/specification/ReleephAuthorFieldSpecification.php',
'ReleephBranch' => 'applications/releeph/storage/ReleephBranch.php',
'ReleephBranchAccessController' => 'applications/releeph/controller/branch/ReleephBranchAccessController.php',
@ -1897,7 +1896,6 @@ phutil_register_library_map(array(
'ReleephFieldSelector' => 'applications/releeph/field/selector/ReleephFieldSelector.php',
'ReleephFieldSpecification' => 'applications/releeph/field/specification/ReleephFieldSpecification.php',
'ReleephFieldSpecificationIncompleteException' => 'applications/releeph/field/exception/ReleephFieldSpecificationIncompleteException.php',
'ReleephInactiveProjectListView' => 'applications/releeph/view/project/list/ReleephInactiveProjectListView.php',
'ReleephIntentFieldSpecification' => 'applications/releeph/field/specification/ReleephIntentFieldSpecification.php',
'ReleephLevelFieldSpecification' => 'applications/releeph/field/specification/ReleephLevelFieldSpecification.php',
'ReleephObjectHandleLoader' => 'applications/releeph/ReleephObjectHandleLoader.php',
@ -1910,6 +1908,7 @@ phutil_register_library_map(array(
'ReleephProjectEditController' => 'applications/releeph/controller/project/ReleephProjectEditController.php',
'ReleephProjectListController' => 'applications/releeph/controller/project/ReleephProjectListController.php',
'ReleephProjectQuery' => 'applications/releeph/query/ReleephProjectQuery.php',
'ReleephProjectSearchEngine' => 'applications/releeph/query/ReleephProjectSearchEngine.php',
'ReleephProjectView' => 'applications/releeph/view/ReleephProjectView.php',
'ReleephProjectViewController' => 'applications/releeph/controller/project/ReleephProjectViewController.php',
'ReleephReasonFieldSpecification' => 'applications/releeph/field/specification/ReleephReasonFieldSpecification.php',
@ -3911,7 +3910,6 @@ phutil_register_library_map(array(
'PonderVoteSaveController' => 'PonderController',
'ProjectRemarkupRule' => 'PhabricatorRemarkupRuleObject',
'QueryFormattingTestCase' => 'PhabricatorTestCase',
'ReleephActiveProjectListView' => 'AphrontView',
'ReleephAuthorFieldSpecification' => 'ReleephFieldSpecification',
'ReleephBranch' => 'ReleephDAO',
'ReleephBranchAccessController' => 'ReleephProjectController',
@ -3920,7 +3918,7 @@ phutil_register_library_map(array(
'ReleephBranchCreateController' => 'ReleephProjectController',
'ReleephBranchEditController' => 'ReleephProjectController',
'ReleephBranchEditor' => 'PhabricatorEditor',
'ReleephBranchNamePreviewController' => 'PhabricatorController',
'ReleephBranchNamePreviewController' => 'ReleephController',
'ReleephBranchPreviewView' => 'AphrontFormControl',
'ReleephBranchViewController' => 'ReleephProjectController',
'ReleephCommitFinderException' => 'Exception',
@ -3936,7 +3934,6 @@ phutil_register_library_map(array(
'ReleephFieldParseException' => 'Exception',
'ReleephFieldSpecification' => 'PhabricatorMarkupInterface',
'ReleephFieldSpecificationIncompleteException' => 'Exception',
'ReleephInactiveProjectListView' => 'AphrontView',
'ReleephIntentFieldSpecification' => 'ReleephFieldSpecification',
'ReleephLevelFieldSpecification' => 'ReleephFieldSpecification',
'ReleephObjectHandleLoader' => 'ObjectHandleLoader',
@ -3950,8 +3947,13 @@ phutil_register_library_map(array(
'ReleephProjectController' => 'ReleephController',
'ReleephProjectCreateController' => 'ReleephProjectController',
'ReleephProjectEditController' => 'ReleephProjectController',
'ReleephProjectListController' => 'PhabricatorController',
'ReleephProjectListController' =>
array(
0 => 'ReleephController',
1 => 'PhabricatorApplicationSearchResultsControllerInterface',
),
'ReleephProjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'ReleephProjectSearchEngine' => 'PhabricatorApplicationSearchEngine',
'ReleephProjectView' => 'AphrontView',
'ReleephProjectViewController' => 'ReleephProjectController',
'ReleephReasonFieldSpecification' => 'ReleephFieldSpecification',

View file

@ -35,7 +35,7 @@ final class PhabricatorApplicationReleeph extends PhabricatorApplication {
'/releeph/' => array(
'' => 'ReleephProjectListController',
'project/' => array(
'(?:(?P<filter>active|inactive)/)?' => 'ReleephProjectListController',
'(?:query/(?P<queryKey>[^/]+)/)?' => 'ReleephProjectListController',
'create/' => 'ReleephProjectCreateController',
'(?P<projectID>[1-9]\d*)/' => array(
'' => 'ReleephProjectViewController',

View file

@ -15,4 +15,27 @@ abstract class ReleephController extends PhabricatorController {
return $response->setContent($page->render());
}
public function buildSideNavView($for_app = false) {
$user = $this->getRequest()->getUser();
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
if ($for_app) {
$nav->addFilter('project/create/', pht('Create Project'));
}
id(new ReleephProjectSearchEngine())
->setViewer($user)
->addNavigationItems($nav->getMenu());
$nav->selectFilter(null);
return $nav;
}
public function buildApplicationMenu() {
return $this->buildSideNavView(true)->getMenu();
}
}

View file

@ -1,95 +1,109 @@
<?php
final class ReleephProjectListController extends ReleephController {
final class ReleephProjectListController extends ReleephController
implements PhabricatorApplicationSearchResultsControllerInterface {
private $filter;
private $queryKey;
public function shouldAllowPublic() {
return true;
}
public function willProcessRequest(array $data) {
$this->filter = idx($data, 'filter', 'active');
$this->queryKey = idx($data, 'queryKey');
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$controller = id(new PhabricatorApplicationSearchController($request))
->setQueryKey($this->queryKey)
->setSearchEngine(new ReleephProjectSearchEngine())
->setNavigation($this->buildSideNavView());
$query = id(new ReleephProjectQuery())
->setViewer($user)
->setOrder(ReleephProjectQuery::ORDER_NAME);
switch ($this->filter) {
case 'inactive':
$query->withActive(0);
$is_active = false;
break;
case 'active':
$query->withActive(1);
$is_active = true;
break;
default:
throw new Exception("Unknown filter '{$this->filter}'!");
}
$pager = new AphrontCursorPagerView();
$pager->readFromRequest($request);
$releeph_projects = $query->executeWithCursorPager($pager);
$releeph_projects_set = new LiskDAOSet();
foreach ($releeph_projects as $releeph_project) {
$releeph_projects_set->addToSet($releeph_project);
}
$panel = new AphrontPanelView();
if ($is_active) {
$view_inactive_link = phutil_tag(
'a',
array(
'href' => '/releeph/project/inactive/',
),
pht('View inactive projects'));
$panel
->setHeader(hsprintf(
'Active Releeph Projects &middot; %s', $view_inactive_link))
->appendChild(
id(new ReleephActiveProjectListView())
->setUser($this->getRequest()->getUser())
->setReleephProjects($releeph_projects));
} else {
$view_active_link = phutil_tag(
'a',
array(
'href' => '/releeph/project/'
),
pht('View active projects'));
$panel
->setHeader(hsprintf(
'Inactive Releeph Projects &middot; %s', $view_active_link))
->appendChild(
id(new ReleephInactiveProjectListView())
->setUser($this->getRequest()->getUser())
->setReleephProjects($releeph_projects));
}
if ($is_active) {
$create_new_project_button = phutil_tag(
'a',
array(
'href' => '/releeph/project/create/',
'class' => 'green button',
),
pht('Create New Project'));
$panel->addButton($create_new_project_button);
}
return $this->buildApplicationPage(
array(
$panel,
$pager,
),
array(
'title' => pht('All Releeph Projects'),
));
return $this->delegateToController($controller);
}
public function renderResultsList(
array $projects,
PhabricatorSavedQuery $query) {
assert_instances_of($projects, 'ReleephProject');
$viewer = $this->getRequest()->getUser();
$list = id(new PhabricatorObjectItemListView())
->setUser($viewer);
foreach ($projects as $project) {
$id = $project->getID();
$item = id(new PhabricatorObjectItemView())
->setHeader($project->getName())
->setHref($this->getApplicationURI("project/{$id}/"));
$edit_uri = $this->getApplicationURI("project/{$id}/edit/");
$item->addAction(
id(new PHUIListItemView())
->setIcon('edit')
->setHref($edit_uri));
if ($project->getIsActive()) {
$disable_uri = $this->getApplicationURI(
"project/{$id}/action/deactivate/");
$item->addAction(
id(new PHUIListItemView())
->setIcon('delete')
->setName(pht('Deactivate'))
->setWorkflow(true)
->setHref($disable_uri));
} else {
$enable_uri = $this->getApplicationURI(
"project/{$id}/action/activate/");
$item->setDisabled(true);
$item->addIcon('none', pht('Inactive'));
$item->addAction(
id(new PHUIListItemView())
->setIcon('new')
->setName(pht('Reactivate'))
->setWorkflow(true)
->setHref($enable_uri));
}
// TODO: See T3551.
$repo = $project->loadPhabricatorRepository();
if ($repo) {
$item->addAttribute(
phutil_tag(
'a',
array(
'href' => '/diffusion/'.$repo->getCallsign().'/',
),
'r'.$repo->getCallsign()));
}
$arc = $project->loadArcanistProject();
if ($arc) {
$item->addAttribute($arc->getName());
}
$list->addItem($item);
}
return $list;
}
public function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$crumbs->addAction(
id(new PHUIListItemView())
->setName(pht('Create Project'))
->setHref($this->getApplicationURI('project/create/'))
->setIcon('create'));
return $crumbs;
}
}

View file

@ -0,0 +1,85 @@
<?php
final class ReleephProjectSearchEngine
extends PhabricatorApplicationSearchEngine {
public function buildSavedQueryFromRequest(AphrontRequest $request) {
$saved = new PhabricatorSavedQuery();
$saved->setParameter('active', $request->getStr('active'));
return $saved;
}
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
$query = id(new ReleephProjectQuery())
->setOrder(ReleephProjectQuery::ORDER_NAME);
$active = $saved->getParameter('active');
$value = idx($this->getActiveValues(), $active);
if ($value !== null) {
$query->withActive($value);
}
return $query;
}
public function buildSearchForm(
AphrontFormView $form,
PhabricatorSavedQuery $saved_query) {
$form->appendChild(
id(new AphrontFormSelectControl())
->setName('active')
->setLabel(pht('Show Projects'))
->setValue($saved_query->getParameter('active'))
->setOptions($this->getActiveOptions()));
}
protected function getURI($path) {
return '/releeph/project/'.$path;
}
public function getBuiltinQueryNames() {
$names = array(
'active' => pht('Active'),
'all' => pht('All'),
);
return $names;
}
public function buildSavedQueryFromBuiltin($query_key) {
$query = $this->newSavedQuery();
$query->setQueryKey($query_key);
switch ($query_key) {
case 'active':
return $query
->setParameter('active', 'active');
case 'all':
return $query;
}
return parent::buildSavedQueryFromBuiltin($query_key);
}
private function getActiveOptions() {
return array(
'all' => pht('Active and Inactive Projects'),
'active' => pht('Active Projects'),
'inactive' => pht('Inactive Projects'),
);
}
private function getActiveValues() {
return array(
'all' => null,
'active' => 1,
'inactive' => 0,
);
}
}

View file

@ -1,102 +0,0 @@
<?php
final class ReleephActiveProjectListView extends AphrontView {
private $releephProjects;
public function setReleephProjects(array $releeph_projects) {
$this->releephProjects = $releeph_projects;
return $this;
}
public function render() {
$rows = array();
foreach ($this->releephProjects as $releeph_project) {
$project_uri = $releeph_project->getURI();
$name_link = phutil_tag(
'a',
array(
'href' => $project_uri,
'style' => 'font-weight: bold;',
),
$releeph_project->getName());
$edit_button = phutil_tag(
'a',
array(
'href' => $releeph_project->getURI('edit/'),
'class' => 'small grey button',
),
'Edit');
$deactivate_button = javelin_tag(
'a',
array(
'href' => $releeph_project->getURI('action/deactivate/'),
'class' => 'small grey button',
'sigil' => 'workflow',
),
'Remove');
$arc_project = $releeph_project->loadArcanistProject();
if ($arc_project) {
$arc_project_name = $arc_project->getName();
} else {
$arc_project_name = phutil_tag(
'i',
array(),
'Deleted Arcanist Project');
}
$repo = $releeph_project->loadPhabricatorRepository();
if ($repo) {
$vcs_type =
PhabricatorRepositoryType::getNameForRepositoryType(
$repo->getVersionControlSystem());
$rows[] = array(
$name_link,
$repo->getName(),
$arc_project_name,
$vcs_type,
$edit_button,
$deactivate_button,
);
} else {
$rows[] = array(
$name_link,
phutil_tag('i', array(), 'Deleted Repository'),
$arc_project_name,
null,
null,
$deactivate_button,
);
}
}
$table = new AphrontTableView($rows);
$table->setHeaders(array(
'Name',
'Repository',
'Arcanist Project',
'Type',
'',
''
));
$table->setColumnClasses(array(
null,
null,
'wide',
null,
'action',
'action'
));
return $table->render();
}
}

View file

@ -1,112 +0,0 @@
<?php
final class ReleephInactiveProjectListView extends AphrontView {
private $releephProjects;
public function setReleephProjects(array $releeph_projects) {
$this->releephProjects = $releeph_projects;
return $this;
}
public function render() {
$rows = array();
$phids = array();
foreach ($this->releephProjects as $releeph_project) {
$phids[] = $releeph_project->getCreatedByUserPHID();
if ($phid = $releeph_project->getDetail('last_deactivated_user')) {
$phids[] = $phid;
}
}
$handles = id(new PhabricatorObjectHandleData($phids))
->setViewer($this->getUser())
->loadHandles();
foreach ($this->releephProjects as $releeph_project) {
$repository = $releeph_project->loadPhabricatorRepository();
if (!$repository) {
// Ignore projects referring to repositories that have been deleted.
continue;
}
$activate_link = javelin_tag(
'a',
array(
'href' => $releeph_project->getURI('action/activate/'),
'class' => 'small grey button',
'sigil' => 'workflow',
),
'Revive');
$delete_link = javelin_tag(
'a',
array(
'href' => $releeph_project->getURI('action/delete/'),
'class' => 'small grey button',
'sigil' => 'workflow',
),
'Delete');
$rows[] = array(
$releeph_project->getName(),
$repository->getName(),
$this->renderCreationInfo($releeph_project, $handles),
$this->renderDeletionInfo($releeph_project, $handles),
$activate_link,
$delete_link,
);
}
$table = new AphrontTableView($rows);
$table->setHeaders(array(
'Name',
'Repository',
'Created',
'Deleted',
'',
'',
));
$table->setColumnClasses(array(
null,
null,
null,
'wide',
'action',
'action',
));
return $table->render();
}
private function renderCreationInfo($releeph_project, $handles) {
$creator = $handles[$releeph_project->getCreatedByUserPHID()];
$when = $releeph_project->getDateCreated();
return hsprintf(
'%s by %s',
phabricator_relative_date($when, $this->user),
$creator->getName());
}
private function renderDeletionInfo($releeph_project, $handles) {
$deleted_on = $releeph_project->getDetail('last_deactivated_time');
$deleted_by_name = null;
$deleted_by_phid = $releeph_project->getDetail('last_deactivated_user');
if ($deleted_by_phid) {
$deleted_by_name = $handles[$deleted_by_phid]->getName();
} else {
$deleted_by_name = 'unknown';
}
return hsprintf(
'%s by %s',
phabricator_relative_date($deleted_on, $this->user),
$deleted_by_name);
}
}