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:
parent
c6ae9c5672
commit
333e377488
3 changed files with 110 additions and 51 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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 )----------------------------------------- */
|
||||
|
|
Loading…
Reference in a new issue