@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.

Use EditEngine for Harbormaster Build Plans, fix some crumbs/mobile stuff

Summary:
Ref T10457.

- Use EditEngine for Build Plans.
- Fix some minor issues with crumbs being inconsistent.
- Fix some minor issues with mobile menus not being consistent/available.

Test Plan:
- Created and edited build plans.
- Poked around in mobile width, verified mobile menu had the right stuff in it.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10457

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

+140 -219
+7 -5
src/__phutil_library_map__.php
··· 1053 1053 'HarbormasterBuildPlanDatasource' => 'applications/harbormaster/typeahead/HarbormasterBuildPlanDatasource.php', 1054 1054 'HarbormasterBuildPlanDefaultEditCapability' => 'applications/harbormaster/capability/HarbormasterBuildPlanDefaultEditCapability.php', 1055 1055 'HarbormasterBuildPlanDefaultViewCapability' => 'applications/harbormaster/capability/HarbormasterBuildPlanDefaultViewCapability.php', 1056 + 'HarbormasterBuildPlanEditEngine' => 'applications/harbormaster/editor/HarbormasterBuildPlanEditEngine.php', 1056 1057 'HarbormasterBuildPlanEditor' => 'applications/harbormaster/editor/HarbormasterBuildPlanEditor.php', 1057 1058 'HarbormasterBuildPlanPHIDType' => 'applications/harbormaster/phid/HarbormasterBuildPlanPHIDType.php', 1058 1059 'HarbormasterBuildPlanQuery' => 'applications/harbormaster/query/HarbormasterBuildPlanQuery.php', ··· 5202 5203 'HarbormasterBuildPlanDatasource' => 'PhabricatorTypeaheadDatasource', 5203 5204 'HarbormasterBuildPlanDefaultEditCapability' => 'PhabricatorPolicyCapability', 5204 5205 'HarbormasterBuildPlanDefaultViewCapability' => 'PhabricatorPolicyCapability', 5206 + 'HarbormasterBuildPlanEditEngine' => 'PhabricatorEditEngine', 5205 5207 'HarbormasterBuildPlanEditor' => 'PhabricatorApplicationTransactionEditor', 5206 5208 'HarbormasterBuildPlanPHIDType' => 'PhabricatorPHIDType', 5207 5209 'HarbormasterBuildPlanQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', ··· 5283 5285 'HarbormasterPlanDisableController' => 'HarbormasterPlanController', 5284 5286 'HarbormasterPlanEditController' => 'HarbormasterPlanController', 5285 5287 'HarbormasterPlanListController' => 'HarbormasterPlanController', 5286 - 'HarbormasterPlanRunController' => 'HarbormasterController', 5288 + 'HarbormasterPlanRunController' => 'HarbormasterPlanController', 5287 5289 'HarbormasterPlanViewController' => 'HarbormasterPlanController', 5288 5290 'HarbormasterPrototypeBuildStepGroup' => 'HarbormasterBuildStepGroup', 5289 5291 'HarbormasterPublishFragmentBuildStepImplementation' => 'HarbormasterBuildStepImplementation', ··· 5296 5298 'HarbormasterScratchTable' => 'HarbormasterDAO', 5297 5299 'HarbormasterSendMessageConduitAPIMethod' => 'HarbormasterConduitAPIMethod', 5298 5300 'HarbormasterSleepBuildStepImplementation' => 'HarbormasterBuildStepImplementation', 5299 - 'HarbormasterStepAddController' => 'HarbormasterController', 5300 - 'HarbormasterStepDeleteController' => 'HarbormasterController', 5301 - 'HarbormasterStepEditController' => 'HarbormasterController', 5302 - 'HarbormasterStepViewController' => 'HarbormasterController', 5301 + 'HarbormasterStepAddController' => 'HarbormasterPlanController', 5302 + 'HarbormasterStepDeleteController' => 'HarbormasterPlanController', 5303 + 'HarbormasterStepEditController' => 'HarbormasterPlanController', 5304 + 'HarbormasterStepViewController' => 'HarbormasterPlanController', 5303 5305 'HarbormasterTargetEngine' => 'Phobject', 5304 5306 'HarbormasterTargetWorker' => 'HarbormasterWorker', 5305 5307 'HarbormasterTestBuildStepGroup' => 'HarbormasterBuildStepGroup',
+3 -3
src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php
··· 76 76 => 'HarbormasterBuildActionController', 77 77 ), 78 78 'plan/' => array( 79 - '(?:query/(?P<queryKey>[^/]+)/)?' 80 - => 'HarbormasterPlanListController', 81 - 'edit/(?:(?P<id>\d+)/)?' => 'HarbormasterPlanEditController', 79 + $this->getQueryRoutePattern() => 'HarbormasterPlanListController', 80 + $this->getEditRoutePattern('edit/') 81 + => 'HarbormasterPlanEditController', 82 82 'order/(?:(?P<id>\d+)/)?' => 'HarbormasterPlanOrderController', 83 83 'disable/(?P<id>\d+)/' => 'HarbormasterPlanDisableController', 84 84 'run/(?P<id>\d+)/' => 'HarbormasterPlanRunController',
+12 -25
src/applications/harbormaster/controller/HarbormasterBuildableListController.php
··· 7 7 } 8 8 9 9 public function handleRequest(AphrontRequest $request) { 10 - $controller = id(new PhabricatorApplicationSearchController()) 11 - ->setQueryKey($request->getURIData('queryKey')) 12 - ->setSearchEngine(new HarbormasterBuildableSearchEngine()) 13 - ->setNavigation($this->buildSideNavView()); 10 + $items = array(); 14 11 15 - return $this->delegateToController($controller); 16 - } 12 + $items[] = id(new PHUIListItemView()) 13 + ->setType(PHUIListItemView::TYPE_LABEL) 14 + ->setName(pht('Build Plans')); 17 15 18 - public function buildSideNavView($for_app = false) { 19 - $user = $this->getRequest()->getUser(); 16 + $items[] = id(new PHUIListItemView()) 17 + ->setType(PHUIListItemView::TYPE_LINK) 18 + ->setName(pht('Manage Build Plans')) 19 + ->setHref($this->getApplicationURI('plan/')); 20 20 21 - $nav = new AphrontSideNavFilterView(); 22 - $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); 23 - 24 - id(new HarbormasterBuildableSearchEngine()) 25 - ->setViewer($user) 26 - ->addNavigationItems($nav->getMenu()); 27 - 28 - $nav->addLabel(pht('Build Plans')); 29 - $nav->addFilter('plan/', pht('Manage Build Plans')); 30 - 31 - $nav->selectFilter(null); 32 - 33 - return $nav; 34 - } 35 - 36 - public function buildApplicationMenu() { 37 - return $this->buildSideNavView(true)->getMenu(); 21 + return id(new HarbormasterBuildableSearchEngine()) 22 + ->setController($this) 23 + ->setNavigationItems($items) 24 + ->buildResponse(); 38 25 } 39 26 40 27 }
+5
src/applications/harbormaster/controller/HarbormasterController.php
··· 2 2 3 3 abstract class HarbormasterController extends PhabricatorController { 4 4 5 + public function buildApplicationMenu() { 6 + return $this->newApplicationMenu() 7 + ->setSearchEngine(new HarbormasterBuildableSearchEngine()); 8 + } 9 + 5 10 protected function addBuildableCrumb( 6 11 PHUICrumbsView $crumbs, 7 12 HarbormasterBuildable $buildable) {
+5
src/applications/harbormaster/controller/HarbormasterPlanController.php
··· 2 2 3 3 abstract class HarbormasterPlanController extends HarbormasterController { 4 4 5 + public function buildApplicationMenu() { 6 + return $this->newApplicationMenu() 7 + ->setSearchEngine(new HarbormasterBuildPlanSearchEngine()); 8 + } 9 + 5 10 protected function buildApplicationCrumbs() { 6 11 $crumbs = parent::buildApplicationCrumbs(); 7 12
+3 -140
src/applications/harbormaster/controller/HarbormasterPlanEditController.php
··· 3 3 final class HarbormasterPlanEditController extends HarbormasterPlanController { 4 4 5 5 public function handleRequest(AphrontRequest $request) { 6 - $viewer = $this->getViewer(); 7 - 8 - $id = $request->getURIData('id'); 9 - if ($id) { 10 - $plan = id(new HarbormasterBuildPlanQuery()) 11 - ->setViewer($viewer) 12 - ->withIDs(array($id)) 13 - ->requireCapabilities( 14 - array( 15 - PhabricatorPolicyCapability::CAN_VIEW, 16 - PhabricatorPolicyCapability::CAN_EDIT, 17 - )) 18 - ->executeOne(); 19 - if (!$plan) { 20 - return new Aphront404Response(); 21 - } 22 - } else { 23 - $this->requireApplicationCapability( 24 - HarbormasterCreatePlansCapability::CAPABILITY); 25 - 26 - $plan = HarbormasterBuildPlan::initializeNewBuildPlan($viewer); 27 - } 28 - 29 - $e_name = true; 30 - $v_name = $plan->getName(); 31 - $v_view = $plan->getViewPolicy(); 32 - $v_edit = $plan->getEditPolicy(); 33 - $validation_exception = null; 34 - if ($request->isFormPost()) { 35 - $xactions = array(); 36 - 37 - $v_name = $request->getStr('name'); 38 - $v_view = $request->getStr('viewPolicy'); 39 - $v_edit = $request->getStr('editPolicy'); 40 - 41 - $e_name = null; 42 - 43 - $type_name = HarbormasterBuildPlanTransaction::TYPE_NAME; 44 - $type_view = PhabricatorTransactions::TYPE_VIEW_POLICY; 45 - $type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY; 46 - 47 - $xactions[] = id(new HarbormasterBuildPlanTransaction()) 48 - ->setTransactionType($type_name) 49 - ->setNewValue($v_name); 50 - 51 - $xactions[] = id(new HarbormasterBuildPlanTransaction()) 52 - ->setTransactionType($type_view) 53 - ->setNewValue($v_view); 54 - 55 - $xactions[] = id(new HarbormasterBuildPlanTransaction()) 56 - ->setTransactionType($type_edit) 57 - ->setNewValue($v_edit); 58 - 59 - $editor = id(new HarbormasterBuildPlanEditor()) 60 - ->setActor($viewer) 61 - ->setContinueOnNoEffect(true) 62 - ->setContentSourceFromRequest($request); 63 - 64 - try { 65 - $editor->applyTransactions($plan, $xactions); 66 - return id(new AphrontRedirectResponse()) 67 - ->setURI($this->getApplicationURI('plan/'.$plan->getID().'/')); 68 - } catch (PhabricatorApplicationTransactionValidationException $ex) { 69 - $validation_exception = $ex; 70 - 71 - $e_name = $validation_exception->getShortMessage( 72 - HarbormasterBuildPlanTransaction::TYPE_NAME); 73 - } 74 - 75 - } 76 - 77 - $is_new = (!$plan->getID()); 78 - if ($is_new) { 79 - $title = pht('New Build Plan'); 80 - $cancel_uri = $this->getApplicationURI('plan/'); 81 - $save_button = pht('Create Build Plan'); 82 - } else { 83 - $id = $plan->getID(); 84 - 85 - $title = pht('Edit Build Plan'); 86 - $cancel_uri = $this->getApplicationURI('plan/'.$plan->getID().'/'); 87 - $save_button = pht('Save Build Plan'); 88 - } 89 - 90 - $policies = id(new PhabricatorPolicyQuery()) 91 - ->setViewer($viewer) 92 - ->setObject($plan) 93 - ->execute(); 94 - 95 - $form = id(new AphrontFormView()) 96 - ->setUser($viewer) 97 - ->appendControl( 98 - id(new AphrontFormTextControl()) 99 - ->setLabel(pht('Plan Name')) 100 - ->setName('name') 101 - ->setError($e_name) 102 - ->setValue($v_name)) 103 - ->appendControl( 104 - id(new AphrontFormPolicyControl()) 105 - ->setCapability(PhabricatorPolicyCapability::CAN_VIEW) 106 - ->setPolicyObject($plan) 107 - ->setPolicies($policies) 108 - ->setValue($v_view) 109 - ->setName('viewPolicy')) 110 - ->appendControl( 111 - id(new AphrontFormPolicyControl()) 112 - ->setCapability(PhabricatorPolicyCapability::CAN_EDIT) 113 - ->setPolicyObject($plan) 114 - ->setPolicies($policies) 115 - ->setValue($v_edit) 116 - ->setName('editPolicy')) 117 - ->appendControl( 118 - id(new AphrontFormSubmitControl()) 119 - ->setValue($save_button) 120 - ->addCancelButton($cancel_uri)); 121 - 122 - $box = id(new PHUIObjectBoxView()) 123 - ->setHeaderText($title) 124 - ->setValidationException($validation_exception) 125 - ->setForm($form); 126 - 127 - $crumbs = $this->buildApplicationCrumbs(); 128 - if ($is_new) { 129 - $crumbs->addTextCrumb(pht('New Build Plan')); 130 - } else { 131 - $id = $plan->getID(); 132 - $crumbs->addTextCrumb( 133 - pht('Plan %d', $id), 134 - $this->getApplicationURI("plan/{$id}/")); 135 - $crumbs->addTextCrumb(pht('Edit')); 136 - } 137 - 138 - return $this->buildApplicationPage( 139 - array( 140 - $crumbs, 141 - $box, 142 - ), 143 - array( 144 - 'title' => $title, 145 - )); 6 + return id(new HarbormasterBuildPlanEditEngine()) 7 + ->setController($this) 8 + ->buildResponse(); 146 9 } 147 10 148 11 }
+6 -40
src/applications/harbormaster/controller/HarbormasterPlanListController.php
··· 7 7 } 8 8 9 9 public function handleRequest(AphrontRequest $request) { 10 - $controller = id(new PhabricatorApplicationSearchController()) 11 - ->setQueryKey($request->getURIData('queryKey')) 12 - ->setSearchEngine(new HarbormasterBuildPlanSearchEngine()) 13 - ->setNavigation($this->buildSideNavView()); 14 - 15 - return $this->delegateToController($controller); 16 - } 17 - 18 - public function buildSideNavView($for_app = false) { 19 - $user = $this->getRequest()->getUser(); 20 - 21 - $nav = new AphrontSideNavFilterView(); 22 - $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); 23 - 24 - if ($for_app) { 25 - $nav->addFilter('new/', pht('New Build Plan')); 26 - } 27 - 28 - id(new HarbormasterBuildPlanSearchEngine()) 29 - ->setViewer($user) 30 - ->addNavigationItems($nav->getMenu()); 31 - 32 - $nav->selectFilter(null); 33 - 34 - return $nav; 35 - } 36 - 37 - public function buildApplicationMenu() { 38 - return $this->buildSideNavView(true)->getMenu(); 10 + return id(new HarbormasterBuildPlanSearchEngine()) 11 + ->setController($this) 12 + ->buildResponse(); 39 13 } 40 14 41 15 protected function buildApplicationCrumbs() { 42 16 $crumbs = parent::buildApplicationCrumbs(); 43 17 44 - $can_create = $this->hasApplicationCapability( 45 - HarbormasterCreatePlansCapability::CAPABILITY); 46 - 47 - $crumbs->addAction( 48 - id(new PHUIListItemView()) 49 - ->setName(pht('New Build Plan')) 50 - ->setHref($this->getApplicationURI('plan/edit/')) 51 - ->setDisabled(!$can_create) 52 - ->setWorkflow(!$can_create) 53 - ->setIcon('fa-plus-square')); 18 + id(new HarbormasterBuildPlanEditEngine()) 19 + ->setViewer($this->getViewer()) 20 + ->addActionToCrumbs($crumbs); 54 21 55 22 return $crumbs; 56 23 } 57 - 58 24 59 25 }
+1 -1
src/applications/harbormaster/controller/HarbormasterPlanRunController.php
··· 1 1 <?php 2 2 3 - final class HarbormasterPlanRunController extends HarbormasterController { 3 + final class HarbormasterPlanRunController extends HarbormasterPlanController { 4 4 5 5 public function handleRequest(AphrontRequest $request) { 6 6 $viewer = $this->getViewer();
+2 -1
src/applications/harbormaster/controller/HarbormasterStepAddController.php
··· 1 1 <?php 2 2 3 - final class HarbormasterStepAddController extends HarbormasterController { 3 + final class HarbormasterStepAddController 4 + extends HarbormasterPlanController { 4 5 5 6 public function handleRequest(AphrontRequest $request) { 6 7 $viewer = $this->getViewer();
+2 -1
src/applications/harbormaster/controller/HarbormasterStepDeleteController.php
··· 1 1 <?php 2 2 3 - final class HarbormasterStepDeleteController extends HarbormasterController { 3 + final class HarbormasterStepDeleteController 4 + extends HarbormasterPlanController { 4 5 5 6 public function handleRequest(AphrontRequest $request) { 6 7 $viewer = $this->getViewer();
+2 -1
src/applications/harbormaster/controller/HarbormasterStepEditController.php
··· 1 1 <?php 2 2 3 - final class HarbormasterStepEditController extends HarbormasterController { 3 + final class HarbormasterStepEditController 4 + extends HarbormasterPlanController { 4 5 5 6 public function handleRequest(AphrontRequest $request) { 6 7 $viewer = $this->getViewer();
+2 -1
src/applications/harbormaster/controller/HarbormasterStepViewController.php
··· 1 1 <?php 2 2 3 - final class HarbormasterStepViewController extends HarbormasterController { 3 + final class HarbormasterStepViewController 4 + extends HarbormasterPlanController { 4 5 5 6 public function handleRequest(AphrontRequest $request) { 6 7 $viewer = $this->getViewer();
+89
src/applications/harbormaster/editor/HarbormasterBuildPlanEditEngine.php
··· 1 + <?php 2 + 3 + final class HarbormasterBuildPlanEditEngine 4 + extends PhabricatorEditEngine { 5 + 6 + const ENGINECONST = 'harbormaster.buildplan'; 7 + 8 + public function isEngineConfigurable() { 9 + return false; 10 + } 11 + 12 + public function getEngineName() { 13 + return pht('Harbormaster Build Plans'); 14 + } 15 + 16 + public function getSummaryHeader() { 17 + return pht('Edit Harbormaster Build Plan Configurations'); 18 + } 19 + 20 + public function getSummaryText() { 21 + return pht('This engine is used to edit Harbormaster build plans.'); 22 + } 23 + 24 + public function getEngineApplicationClass() { 25 + return 'PhabricatorHarbormasterApplication'; 26 + } 27 + 28 + protected function newEditableObject() { 29 + $viewer = $this->getViewer(); 30 + return HarbormasterBuildPlan::initializeNewBuildPlan($viewer); 31 + } 32 + 33 + protected function newObjectQuery() { 34 + return new HarbormasterBuildPlanQuery(); 35 + } 36 + 37 + protected function getObjectCreateTitleText($object) { 38 + return pht('Create Build Plan'); 39 + } 40 + 41 + protected function getObjectCreateButtonText($object) { 42 + return pht('Create Build Plan'); 43 + } 44 + 45 + protected function getObjectEditTitleText($object) { 46 + return pht('Edit Build Plan: %s', $object->getName()); 47 + } 48 + 49 + protected function getObjectEditShortText($object) { 50 + return pht('Edit Build Plan'); 51 + } 52 + 53 + protected function getObjectCreateShortText() { 54 + return pht('Create Build Plan'); 55 + } 56 + 57 + protected function getEditorURI() { 58 + return '/harbormaster/plan/edit/'; 59 + } 60 + 61 + protected function getObjectCreateCancelURI($object) { 62 + return '/harbormaster/plan/'; 63 + } 64 + 65 + protected function getObjectViewURI($object) { 66 + $id = $object->getID(); 67 + return "/harbormaster/plan/{$id}/"; 68 + } 69 + 70 + protected function getCreateNewObjectPolicy() { 71 + return $this->getApplication()->getPolicy( 72 + HarbormasterCreatePlansCapability::CAPABILITY); 73 + } 74 + 75 + protected function buildCustomEditFields($object) { 76 + return array( 77 + id(new PhabricatorTextEditField()) 78 + ->setKey('name') 79 + ->setLabel(pht('Name')) 80 + ->setIsRequired(true) 81 + ->setTransactionType(HarbormasterBuildPlanTransaction::TYPE_NAME) 82 + ->setDescription(pht('The build plan name.')) 83 + ->setConduitDescription(pht('Rename the plan.')) 84 + ->setConduitTypeDescription(pht('New plan name.')) 85 + ->setValue($object->getName()), 86 + ); 87 + } 88 + 89 + }
+1 -1
src/applications/harbormaster/editor/HarbormasterBuildPlanEditor.php
··· 90 90 $error = new PhabricatorApplicationTransactionValidationError( 91 91 $type, 92 92 pht('Required'), 93 - pht('Plan name is required.'), 93 + pht('You must choose a name for your build plan.'), 94 94 last($xactions)); 95 95 96 96 $error->setIsMissingFieldError(true);