@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Rename project -> product on edit/create UIs

Summary: Ref T3092. Ref T3549. Modernize the product creation and edit UIs and make them say "product" instead of "project".

Test Plan:
- Created products.
- Edited products.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T3092, T3549

Differential Revision: https://secure.phabricator.com/D8636

+94 -106
+4 -4
src/__phutil_library_map__.php
··· 2516 2516 'ReleephPHIDTypeRequest' => 'applications/releeph/phid/ReleephPHIDTypeRequest.php', 2517 2517 'ReleephProductActionController' => 'applications/releeph/controller/project/ReleephProductActionController.php', 2518 2518 'ReleephProductController' => 'applications/releeph/controller/project/ReleephProductController.php', 2519 + 'ReleephProductCreateController' => 'applications/releeph/controller/project/ReleephProductCreateController.php', 2520 + 'ReleephProductEditController' => 'applications/releeph/controller/project/ReleephProductEditController.php', 2519 2521 'ReleephProductEditor' => 'applications/releeph/editor/ReleephProductEditor.php', 2520 2522 'ReleephProductHistoryController' => 'applications/releeph/controller/project/ReleephProductHistoryController.php', 2521 2523 'ReleephProductListController' => 'applications/releeph/controller/project/ReleephProductListController.php', ··· 2525 2527 'ReleephProductViewController' => 'applications/releeph/controller/project/ReleephProductViewController.php', 2526 2528 'ReleephProject' => 'applications/releeph/storage/ReleephProject.php', 2527 2529 'ReleephProjectController' => 'applications/releeph/controller/ReleephProjectController.php', 2528 - 'ReleephProjectCreateController' => 'applications/releeph/controller/project/ReleephProjectCreateController.php', 2529 - 'ReleephProjectEditController' => 'applications/releeph/controller/project/ReleephProjectEditController.php', 2530 2530 'ReleephProjectQuery' => 'applications/releeph/query/ReleephProjectQuery.php', 2531 2531 'ReleephReasonFieldSpecification' => 'applications/releeph/field/specification/ReleephReasonFieldSpecification.php', 2532 2532 'ReleephRequest' => 'applications/releeph/storage/ReleephRequest.php', ··· 5491 5491 'ReleephPHIDTypeRequest' => 'PhabricatorPHIDType', 5492 5492 'ReleephProductActionController' => 'ReleephProductController', 5493 5493 'ReleephProductController' => 'ReleephController', 5494 + 'ReleephProductCreateController' => 'ReleephProjectController', 5495 + 'ReleephProductEditController' => 'ReleephProductController', 5494 5496 'ReleephProductEditor' => 'PhabricatorApplicationTransactionEditor', 5495 5497 'ReleephProductHistoryController' => 'ReleephProductController', 5496 5498 'ReleephProductListController' => ··· 5512 5514 1 => 'PhabricatorPolicyInterface', 5513 5515 ), 5514 5516 'ReleephProjectController' => 'ReleephController', 5515 - 'ReleephProjectCreateController' => 'ReleephProjectController', 5516 - 'ReleephProjectEditController' => 'ReleephProjectController', 5517 5517 'ReleephProjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 5518 5518 'ReleephReasonFieldSpecification' => 'ReleephFieldSpecification', 5519 5519 'ReleephRequest' =>
+2 -2
src/applications/releeph/application/PhabricatorApplicationReleeph.php
··· 36 36 '' => 'ReleephProductListController', 37 37 'project/' => array( 38 38 '(?:query/(?P<queryKey>[^/]+)/)?' => 'ReleephProductListController', 39 - 'create/' => 'ReleephProjectCreateController', 39 + 'create/' => 'ReleephProductCreateController', 40 40 '(?P<projectID>[1-9]\d*)/' => array( 41 41 '(?:query/(?P<queryKey>[^/]+)/)?' => 'ReleephProductViewController', 42 - 'edit/' => 'ReleephProjectEditController', 42 + 'edit/' => 'ReleephProductEditController', 43 43 'cutbranch/' => 'ReleephBranchCreateController', 44 44 'action/(?P<action>.+)/' => 'ReleephProductActionController', 45 45 'history/' => 'ReleephProductHistoryController',
+13 -14
src/applications/releeph/controller/project/ReleephProjectCreateController.php src/applications/releeph/controller/project/ReleephProductCreateController.php
··· 1 1 <?php 2 2 3 - final class ReleephProjectCreateController extends ReleephProjectController { 3 + final class ReleephProductCreateController extends ReleephProjectController { 4 4 5 5 public function processRequest() { 6 6 $request = $this->getRequest(); ··· 18 18 if (!$name) { 19 19 $e_name = pht('Required'); 20 20 $errors[] = pht( 21 - 'Your Releeph project should have a simple descriptive name.'); 21 + 'Your product should have a simple, descriptive name.'); 22 22 } 23 23 24 24 if (!$trunk_branch) { ··· 31 31 $pr_repository = $arc_project->loadRepository(); 32 32 33 33 if (!$errors) { 34 - $releeph_project = id(new ReleephProject()) 34 + $releeph_product = id(new ReleephProject()) 35 35 ->setName($name) 36 36 ->setTrunkBranch($trunk_branch) 37 37 ->setRepositoryPHID($pr_repository->getPHID()) ··· 40 40 ->setIsActive(1); 41 41 42 42 try { 43 - $releeph_project->save(); 43 + $releeph_product->save(); 44 44 45 45 return id(new AphrontRedirectResponse()) 46 - ->setURI($releeph_project->getURI()); 46 + ->setURI($releeph_product->getURI()); 47 47 } catch (AphrontQueryDuplicateKeyException $ex) { 48 48 $e_name = pht('Not Unique'); 49 - $errors[] = pht( 50 - 'Another project already uses this name.'); 49 + $errors[] = pht('Another product already uses this name.'); 51 50 } 52 51 } 53 52 } 54 53 55 54 $arc_project_options = $this->getArcProjectSelectOptions($arc_projects); 56 55 57 - $project_name_input = id(new AphrontFormTextControl()) 56 + $product_name_input = id(new AphrontFormTextControl()) 58 57 ->setLabel(pht('Name')) 59 58 ->setDisableAutocomplete(true) 60 59 ->setName('name') ··· 79 78 80 79 $branch_name_preview = id(new ReleephBranchPreviewView()) 81 80 ->setLabel(pht('Example Branch')) 82 - ->addControl('projectName', $project_name_input) 81 + ->addControl('projectName', $product_name_input) 83 82 ->addControl('arcProjectID', $arc_project_input) 84 83 ->addStatic('template', '') 85 84 ->addStatic('isSymbolic', false); 86 85 87 86 $form = id(new AphrontFormView()) 88 87 ->setUser($request->getUser()) 89 - ->appendChild($project_name_input) 88 + ->appendChild($product_name_input) 90 89 ->appendChild($arc_project_input) 91 90 ->appendChild( 92 91 id(new AphrontFormTextControl()) ··· 100 99 ->appendChild( 101 100 id(new AphrontFormSubmitControl()) 102 101 ->addCancelButton('/releeph/project/') 103 - ->setValue(pht('Create'))); 102 + ->setValue(pht('Create Release Product'))); 104 103 105 104 $form_box = id(new PHUIObjectBoxView()) 106 - ->setHeaderText(pht('Create New Project')) 105 + ->setHeaderText(pht('Create New Product')) 107 106 ->setFormErrors($errors) 108 107 ->setForm($form); 109 108 110 109 $crumbs = $this->buildApplicationCrumbs(); 111 - $crumbs->addTextCrumb(pht('New Project')); 110 + $crumbs->addTextCrumb(pht('New Product')); 112 111 113 112 return $this->buildApplicationPage( 114 113 array( ··· 116 115 $form_box, 117 116 ), 118 117 array( 119 - 'title' => pht('Create New Project'), 118 + 'title' => pht('Create New Product'), 120 119 'device' => true, 121 120 )); 122 121 }
+75 -86
src/applications/releeph/controller/project/ReleephProjectEditController.php src/applications/releeph/controller/project/ReleephProductEditController.php
··· 1 1 <?php 2 2 3 - final class ReleephProjectEditController extends ReleephProjectController { 3 + final class ReleephProductEditController extends ReleephProductController { 4 + 5 + private $productID; 6 + 7 + public function willProcessRequest(array $data) { 8 + $this->productID = $data['projectID']; 9 + } 4 10 5 11 public function processRequest() { 6 12 $request = $this->getRequest(); 13 + $viewer = $request->getUser(); 14 + 15 + $product = id(new ReleephProjectQuery()) 16 + ->setViewer($viewer) 17 + ->withIDs(array($this->productID)) 18 + ->requireCapabilities( 19 + array( 20 + PhabricatorPolicyCapability::CAN_VIEW, 21 + PhabricatorPolicyCapability::CAN_EDIT, 22 + )) 23 + ->executeOne(); 24 + if (!$product) { 25 + return new Aphront404Response(); 26 + } 27 + $this->setProduct($product); 7 28 8 29 $e_name = true; 9 30 $e_trunk_branch = true; 10 31 $e_branch_template = false; 11 32 $errors = array(); 12 33 13 - $project_name = $request->getStr('name', 14 - $this->getReleephProject()->getName()); 34 + $product_name = $request->getStr('name', $product->getName()); 15 35 16 - $trunk_branch = $request->getStr('trunkBranch', 17 - $this->getReleephProject()->getTrunkBranch()); 36 + $trunk_branch = $request->getStr('trunkBranch', $product->getTrunkBranch()); 18 37 $branch_template = $request->getStr('branchTemplate'); 19 38 if ($branch_template === null) { 20 - $branch_template = 21 - $this->getReleephProject()->getDetail('branchTemplate'); 39 + $branch_template = $product->getDetail('branchTemplate'); 22 40 } 23 41 $pick_failure_instructions = $request->getStr('pickFailureInstructions', 24 - $this->getReleephProject()->getDetail('pick_failure_instructions')); 42 + $product->getDetail('pick_failure_instructions')); 25 43 $test_paths = $request->getStr('testPaths'); 26 44 if ($test_paths !== null) { 27 45 $test_paths = array_filter(explode("\n", $test_paths)); 28 46 } else { 29 - $test_paths = $this->getReleephProject()->getDetail('testPaths', array()); 47 + $test_paths = $product->getDetail('testPaths', array()); 30 48 } 31 49 32 - $arc_project_id = $this->getReleephProject()->getArcanistProjectID(); 50 + $arc_project_id = $product->getArcanistProjectID(); 33 51 34 52 if ($request->isFormPost()) { 35 53 $pusher_phids = $request->getArr('pushers'); 36 54 37 - if (!$project_name) { 55 + if (!$product_name) { 38 56 $e_name = pht('Required'); 39 57 $errors[] = 40 - pht('Your releeph project should have a simple descriptive name'); 58 + pht('Your releeph product should have a simple descriptive name.'); 41 59 } 42 60 43 61 if (!$trunk_branch) { ··· 46 64 pht('You must specify which branch you will be picking from.'); 47 65 } 48 66 49 - $other_releeph_projects = id(new ReleephProject()) 50 - ->loadAllWhere('id <> %d', $this->getReleephProject()->getID()); 51 - $other_releeph_project_names = mpull($other_releeph_projects, 67 + $other_releeph_products = id(new ReleephProject()) 68 + ->loadAllWhere('id != %d', $product->getID()); 69 + $other_releeph_product_names = mpull($other_releeph_products, 52 70 'getName', 'getID'); 53 71 54 - if (in_array($project_name, $other_releeph_project_names)) { 55 - $errors[] = pht("Releeph project name %s is already taken", 56 - $project_name); 72 + if (in_array($product_name, $other_releeph_product_names)) { 73 + $errors[] = pht("Releeph product name %s is already taken", 74 + $product_name); 57 75 } 58 76 59 77 foreach ($test_paths as $test_path) { ··· 65 83 } 66 84 } 67 85 68 - $project = $this->getReleephProject() 86 + $product 69 87 ->setTrunkBranch($trunk_branch) 70 88 ->setDetail('pushers', $pusher_phids) 71 89 ->setDetail('pick_failure_instructions', $pick_failure_instructions) ··· 78 96 if ($branch_template) { 79 97 list($branch_name, $template_errors) = id(new ReleephBranchTemplate()) 80 98 ->setCommitHandle($fake_commit_handle) 81 - ->setReleephProjectName($project_name) 99 + ->setReleephProjectName($product_name) 82 100 ->interpolate($branch_template); 83 101 84 102 if ($template_errors) { ··· 90 108 } 91 109 92 110 if (!$errors) { 93 - $project->save(); 111 + $product->save(); 94 112 95 - return id(new AphrontRedirectResponse()) 96 - ->setURI('/releeph/project/'); 113 + return id(new AphrontRedirectResponse())->setURI($product->getURI()); 97 114 } 98 115 } 99 116 100 - $error_view = null; 101 - if ($errors) { 102 - $error_view = new AphrontErrorView(); 103 - $error_view->setErrors($errors); 104 - } 105 - 106 - $projects = mpull( 107 - id(new PhabricatorProject())->loadAll(), 108 - 'getName', 109 - 'getID'); 110 - 111 - $projects[0] = '-'; // no project associated, that's ok 112 - 113 117 $pusher_phids = $request->getArr( 114 118 'pushers', 115 - $this->getReleephProject()->getDetail('pushers', array())); 119 + $product->getDetail('pushers', array())); 116 120 117 121 $handles = id(new PhabricatorHandleQuery()) 118 122 ->setViewer($request->getUser()) ··· 121 125 122 126 $pusher_handles = array_select_keys($handles, $pusher_phids); 123 127 124 - $basic_inset = id(new AphrontFormInsetView()) 125 - ->setTitle(pht('Basics')) 128 + $form = id(new AphrontFormView()) 129 + ->setUser($request->getUser()) 126 130 ->appendChild( 127 131 id(new AphrontFormTextControl()) 128 132 ->setLabel(pht('Name')) 129 133 ->setName('name') 130 - ->setValue($project_name) 134 + ->setValue($product_name) 131 135 ->setError($e_name) 132 136 ->setCaption(pht('A name like "Thrift" but not "Thrift releases".'))) 133 137 ->appendChild( 134 138 id(new AphrontFormStaticControl()) 135 139 ->setLabel(pht('Repository')) 136 140 ->setValue( 137 - $this 138 - ->getReleephProject() 139 - ->loadPhabricatorRepository() 140 - ->getName())) 141 + $product 142 + ->loadPhabricatorRepository() 143 + ->getName())) 141 144 ->appendChild( 142 145 id(new AphrontFormStaticControl()) 143 146 ->setLabel(pht('Arc Project')) 144 147 ->setValue( 145 - $this->getReleephProject()->loadArcanistProject()->getName())) 148 + $product->loadArcanistProject()->getName())) 146 149 ->appendChild( 147 150 id(new AphrontFormStaticControl()) 148 151 ->setLabel(pht('Releeph Project PHID')) 149 152 ->setValue( 150 - $this->getReleephProject()->getPHID())) 153 + $product->getPHID())) 151 154 ->appendChild( 152 155 id(new AphrontFormTextControl()) 153 156 ->setLabel(pht('Trunk')) ··· 172 175 'in this project. One string per line. '. 173 176 'Examples: \'__tests__\', \'/javatests/\'...'))); 174 177 175 - $pushers_inset = id(new AphrontFormInsetView()) 176 - ->setTitle(pht('Pushers')) 177 - ->appendChild( 178 - pht('Pushers are allowed to approve Releeph requests to be committed. '. 179 - 'to this project\'s branches. If you leave this blank then anyone '. 180 - 'is allowed to approve requests.')) 181 - ->appendChild( 182 - id(new AphrontFormTokenizerControl()) 183 - ->setLabel(pht('Pushers')) 184 - ->setName('pushers') 185 - ->setDatasource('/typeahead/common/users/') 186 - ->setValue($pusher_handles)); 187 - 188 - // Build the Template inset 189 - $help_markup = PhabricatorMarkupEngine::renderOneObject( 190 - id(new PhabricatorMarkupOneOff())->setContent($this->getBranchHelpText()), 191 - 'default', 192 - $request->getUser()); 193 - 194 178 $branch_template_input = id(new AphrontFormTextControl()) 195 179 ->setName('branchTemplate') 196 180 ->setValue($branch_template) 197 - ->setLabel('Template') 181 + ->setLabel('Branch Template') 198 182 ->setError($e_branch_template) 199 183 ->setCaption( 200 184 pht("Leave this blank to use your installation's default.")); ··· 204 188 ->addControl('template', $branch_template_input) 205 189 ->addStatic('arcProjectID', $arc_project_id) 206 190 ->addStatic('isSymbolic', false) 207 - ->addStatic('projectName', $this->getReleephProject()->getName()); 191 + ->addStatic('projectName', $product->getName()); 208 192 209 - $template_inset = id(new AphrontFormInsetView()) 210 - ->setTitle(pht('Branch Cutting')) 193 + $form 211 194 ->appendChild( 212 - pht('Provide a pattern for creating new branches.')) 195 + id(new AphrontFormTokenizerControl()) 196 + ->setLabel(pht('Pushers')) 197 + ->setName('pushers') 198 + ->setDatasource('/typeahead/common/users/') 199 + ->setValue($pusher_handles)) 213 200 ->appendChild($branch_template_input) 214 201 ->appendChild($branch_template_preview) 215 - ->appendChild($help_markup); 216 - 217 - // Build the form 218 - $form = id(new AphrontFormView()) 219 - ->setUser($request->getUser()) 220 - ->appendChild($basic_inset) 221 - ->appendChild($pushers_inset) 222 - ->appendChild($template_inset); 202 + ->appendRemarkupInstructions($this->getBranchHelpText()); 223 203 224 204 $form 225 205 ->appendChild( ··· 227 207 ->addCancelButton('/releeph/project/') 228 208 ->setValue(pht('Save'))); 229 209 230 - $panel = id(new AphrontPanelView()) 231 - ->setHeader(pht('Edit Releeph Project')) 232 - ->appendChild($form) 233 - ->setWidth(AphrontPanelView::WIDTH_FORM); 210 + $box = id(new PHUIObjectBoxView()) 211 + ->setHeaderText(pht('Edit Releeph Product')) 212 + ->setFormErrors($errors) 213 + ->appendChild($form); 214 + 215 + $crumbs = $this->buildApplicationCrumbs(); 216 + $crumbs->addTextCrumb(pht('Edit Product')); 234 217 235 218 return $this->buildStandardPageResponse( 236 - array($error_view, $panel), 237 - array('title' => pht('Edit Releeph Project'))); 219 + array( 220 + $crumbs, 221 + $box, 222 + ), 223 + array( 224 + 'title' => pht('Edit Releeph Product'), 225 + 'device' => true, 226 + )); 238 227 } 239 228 240 229 private function getBranchHelpText() { ··· 244 233 245 234 | Code | Meaning 246 235 | ----- | ------- 247 - | `%P` | The name of your project, with spaces changed to "-". 236 + | `%P` | The name of your product, with spaces changed to "-". 248 237 | `%p` | Like %P, but all lowercase. 249 238 | `%Y` | The four digit year associated with the branch date. 250 239 | `%m` | The two digit month. ··· 263 252 releases/%Y-%M-%d-%v 264 253 => releases/2012-30-16-rHERGE32cd512a52b7 265 254 266 - Include a second hierarchy if you share your repository with other projects: 255 + Include a second hierarchy if you share your repository with other products: 267 256 268 257 lang=none 269 258 releases/%P/%p-release-%Y%m%d-%V