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:
parent
904a24c1df
commit
215da7728f
7 changed files with 213 additions and 303 deletions
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 · %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 · %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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue