1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-11 15:21:03 +01:00

Modernize Releeph project create controller

Summary:
Ref T3092.

  - Check for a duplicate key error;
  - do less single loading and use Query classes;
  - use responsive UI elements;
  - add crumbs.

Test Plan: Created a new project, and hit error cases.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T3092

Differential Revision: https://secure.phabricator.com/D6629
This commit is contained in:
epriestley 2013-07-30 12:38:11 -07:00
parent c6ae9c5672
commit 333e377488
3 changed files with 110 additions and 51 deletions

View file

@ -8,15 +8,7 @@ final class ReleephProjectCreateController extends ReleephProjectController {
$trunk_branch = trim($request->getStr('trunkBranch'));
$arc_pr_id = $request->getInt('arcPrID');
// Only allow arc projects with repositories. Sort and re-key by ID.
$arc_projects = id(new PhabricatorRepositoryArcanistProject())->loadAll();
$arc_projects = mpull(
msort(
mfilter($arc_projects, 'getRepositoryID'),
'getName'),
null,
'getID');
$arc_projects = $this->loadArcProjects();
$e_name = true;
$e_trunk_branch = true;
@ -25,20 +17,14 @@ final class ReleephProjectCreateController extends ReleephProjectController {
if ($request->isFormPost()) {
if (!$name) {
$e_name = pht('Required');
$errors[] =
pht('Your Releeph project should have a simple descriptive name.');
$errors[] = pht(
'Your Releeph project should have a simple descriptive name.');
}
if (!$trunk_branch) {
$e_trunk_branch = pht('Required');
$errors[] =
pht('You must specify which branch you will be picking from.');
}
$all_names = mpull(id(new ReleephProject())->loadAll(), 'getName');
if (in_array($name, $all_names)) {
$errors[] = pht('Releeph project name %s is already taken', $name);
$errors[] = pht(
'You must specify which branch you will be picking from.');
}
$arc_project = $arc_projects[$arc_pr_id];
@ -52,10 +38,18 @@ final class ReleephProjectCreateController extends ReleephProjectController {
->setRepositoryPHID($pr_repository->getPHID())
->setArcanistProjectID($arc_project->getID())
->setCreatedByUserPHID($request->getUser()->getPHID())
->setIsActive(1)
->save();
->setIsActive(1);
return id(new AphrontRedirectResponse())->setURI('/releeph/');
try {
$releeph_project->save();
return id(new AphrontRedirectResponse())
->setURI($releeph_project->getURI());
} catch (AphrontQueryDuplicateKeyException $ex) {
$e_name = pht('Not Unique');
$errors[] = pht(
'Another project already uses this name.');
}
}
}
@ -63,29 +57,9 @@ final class ReleephProjectCreateController extends ReleephProjectController {
if ($errors) {
$error_view = new AphrontErrorView();
$error_view->setErrors($errors);
$error_view->setTitle(pht('Form Errors'));
}
// Make our own optgroup select control
$arc_project_choices = array();
$pr_repositories = mpull(
msort(
array_filter(
// Some arc-projects don't have repositories
mpull($arc_projects, 'loadRepository')),
'getName'),
null,
'getID');
foreach ($pr_repositories as $pr_repo_id => $pr_repository) {
$options = array();
foreach ($arc_projects as $arc_project) {
if ($arc_project->getRepositoryID() == $pr_repo_id) {
$options[$arc_project->getID()] = $arc_project->getName();
}
}
$arc_project_choices[$pr_repository->getName()] = $options;
}
$arc_project_options = $this->getArcProjectSelectOptions($arc_projects);
$project_name_input = id(new AphrontFormTextControl())
->setLabel(pht('Name'))
@ -108,7 +82,7 @@ final class ReleephProjectCreateController extends ReleephProjectController {
'target' => '_blank',
),
'here')))
->setOptions($arc_project_choices);
->setOptions($arc_project_options);
$branch_name_preview = id(new ReleephBranchPreviewView())
->setLabel(pht('Example Branch'))
@ -119,6 +93,7 @@ final class ReleephProjectCreateController extends ReleephProjectController {
$form = id(new AphrontFormView())
->setUser($request->getUser())
->setFlexible(true)
->appendChild($project_name_input)
->appendChild($arc_project_input)
->appendChild(
@ -135,15 +110,62 @@ final class ReleephProjectCreateController extends ReleephProjectController {
->addCancelButton('/releeph/project/')
->setValue(pht('Create')));
$panel = id(new AphrontPanelView())
->setHeader(pht('Create Releeph Project'))
->appendChild($form)
->setWidth(AphrontPanelView::WIDTH_FORM);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addCrumb(
id(new PhabricatorCrumbView())
->setName(pht('New Project')));
return $this->buildStandardPageResponse(
array($error_view, $panel),
return $this->buildApplicationPage(
array(
'title' => pht('Create New Releeph Project')
$crumbs,
$error_view,
$form,
),
array(
'title' => pht('Create New Project'),
'dust' => true,
'device' => true,
));
}
private function loadArcProjects() {
$viewer = $this->getRequest()->getUser();
$projects = id(new PhabricatorRepositoryArcanistProjectQuery())
->setViewer($viewer)
->needRepositories(true)
->execute();
$projects = mfilter($projects, 'getRepository');
$projects = msort($projects, 'getName');
return $projects;
}
private function getArcProjectSelectOptions(array $arc_projects) {
assert_instances_of($arc_projects, 'PhabricatorRepositoryArcanistProject');
$repos = mpull($arc_projects, 'getRepository');
$repos = mpull($repos, null, 'getID');
$groups = array();
foreach ($arc_projects as $arc_project) {
$id = $arc_project->getID();
$repo_id = $arc_project->getRepository()->getID();
$groups[$repo_id][$id] = $arc_project->getName();
}
$choices = array();
foreach ($groups as $repo_id => $group) {
$repo_name = $repos[$repo_id]->getName();
$callsign = $repos[$repo_id]->getCallsign();
$name = "r{$callsign} ({$repo_name})";
$choices[$name] = $group;
}
ksort($choices);
return $choices;
}
}

View file

@ -9,6 +9,8 @@ final class PhabricatorRepositoryArcanistProjectQuery
private $ids;
private $phids;
private $needRepositories;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
@ -19,6 +21,11 @@ final class PhabricatorRepositoryArcanistProjectQuery
return $this;
}
public function needRepositories($need_repositories) {
$this->needRepositories = $need_repositories;
return $this;
}
protected function loadPage() {
$table = new PhabricatorRepositoryArcanistProject();
$conn_r = $table->establishConnection('r');
@ -34,6 +41,24 @@ final class PhabricatorRepositoryArcanistProjectQuery
return $table->loadAllFromArray($data);
}
public function willFilterPage(array $projects) {
assert_instances_of($projects, 'PhabricatorRepositoryArcanistProject');
if ($this->needRepositories) {
$repository_ids = mpull($projects, 'getRepositoryID');
$repositories = id(new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->withIDs($repository_ids)
->execute();
foreach ($projects as $project) {
$repo = idx($repositories, $project->getRepositoryID());
$project->attachRepository($repo);
}
}
return $projects;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();

View file

@ -14,6 +14,8 @@ final class PhabricatorRepositoryArcanistProject
protected $symbolIndexLanguages = array();
protected $symbolIndexProjects = array();
private $repository = self::ATTACHABLE;
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
@ -30,6 +32,7 @@ final class PhabricatorRepositoryArcanistProject
PhabricatorRepositoryPHIDTypeArcanistProject::TYPECONST);
}
// TODO: Remove.
public function loadRepository() {
if (!$this->getRepositoryID()) {
return null;
@ -51,6 +54,15 @@ final class PhabricatorRepositoryArcanistProject
return $result;
}
public function getRepository() {
return $this->assertAttached($this->repository);
}
public function attachRepository(PhabricatorRepository $repository = null) {
$this->repository = $repository;
return $this;
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */