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

Show a more reasonable status element for pull requests

Summary:
Ref T182. Replace the total mess we had before with a sort-of-reasonable element.

This automatically updates using "javascript".

Test Plan:
{F901983}

{F901984}

Used "Land Revision", saw the land status go from "Waiting" -> "Working" -> "Landed" without having to mash reload over and over again.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T182

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

+237 -23
+7
resources/celerity/map.php
··· 373 373 'rsrc/js/application/diffusion/behavior-locate-file.js' => '6d3e1947', 374 374 'rsrc/js/application/diffusion/behavior-pull-lastmodified.js' => 'f01586dc', 375 375 'rsrc/js/application/doorkeeper/behavior-doorkeeper-tag.js' => 'e5822781', 376 + 'rsrc/js/application/drydock/drydock-live-operation-status.js' => '901935ef', 376 377 'rsrc/js/application/files/behavior-icon-composer.js' => '8ef9ab58', 377 378 'rsrc/js/application/files/behavior-launch-icon-composer.js' => '48086888', 378 379 'rsrc/js/application/herald/HeraldRuleEditor.js' => '91a6031b', ··· 576 577 'javelin-behavior-diffusion-locate-file' => '6d3e1947', 577 578 'javelin-behavior-diffusion-pull-lastmodified' => 'f01586dc', 578 579 'javelin-behavior-doorkeeper-tag' => 'e5822781', 580 + 'javelin-behavior-drydock-live-operation-status' => '901935ef', 579 581 'javelin-behavior-durable-column' => 'c72aa091', 580 582 'javelin-behavior-error-log' => '6882e80a', 581 583 'javelin-behavior-event-all-day' => '38dcf3c8', ··· 1517 1519 'javelin-behavior', 1518 1520 'javelin-dom', 1519 1521 'javelin-stratcom', 1522 + ), 1523 + '901935ef' => array( 1524 + 'javelin-behavior', 1525 + 'javelin-dom', 1526 + 'javelin-request', 1520 1527 ), 1521 1528 '91a6031b' => array( 1522 1529 'multirow-row-manager',
+4
src/__phutil_library_map__.php
··· 885 885 'DrydockRepositoryOperationPHIDType' => 'applications/drydock/phid/DrydockRepositoryOperationPHIDType.php', 886 886 'DrydockRepositoryOperationQuery' => 'applications/drydock/query/DrydockRepositoryOperationQuery.php', 887 887 'DrydockRepositoryOperationSearchEngine' => 'applications/drydock/query/DrydockRepositoryOperationSearchEngine.php', 888 + 'DrydockRepositoryOperationStatusController' => 'applications/drydock/controller/DrydockRepositoryOperationStatusController.php', 889 + 'DrydockRepositoryOperationStatusView' => 'applications/drydock/view/DrydockRepositoryOperationStatusView.php', 888 890 'DrydockRepositoryOperationType' => 'applications/drydock/operation/DrydockRepositoryOperationType.php', 889 891 'DrydockRepositoryOperationUpdateWorker' => 'applications/drydock/worker/DrydockRepositoryOperationUpdateWorker.php', 890 892 'DrydockRepositoryOperationViewController' => 'applications/drydock/controller/DrydockRepositoryOperationViewController.php', ··· 4672 4674 'DrydockRepositoryOperationPHIDType' => 'PhabricatorPHIDType', 4673 4675 'DrydockRepositoryOperationQuery' => 'DrydockQuery', 4674 4676 'DrydockRepositoryOperationSearchEngine' => 'PhabricatorApplicationSearchEngine', 4677 + 'DrydockRepositoryOperationStatusController' => 'DrydockController', 4678 + 'DrydockRepositoryOperationStatusView' => 'AphrontView', 4675 4679 'DrydockRepositoryOperationType' => 'Phobject', 4676 4680 'DrydockRepositoryOperationUpdateWorker' => 'DrydockWorker', 4677 4681 'DrydockRepositoryOperationViewController' => 'DrydockController',
+6 -23
src/applications/differential/controller/DifferentialRevisionViewController.php
··· 1060 1060 1061 1061 $operation = head(msort($operations, 'getID')); 1062 1062 1063 - // TODO: This is completely made up for now, give it useful information and 1064 - // a sweet progress bar. 1063 + $box_view = id(new PHUIObjectBoxView()) 1064 + ->setHeaderText(pht('Active Operations')); 1065 1065 1066 - switch ($operation->getOperationState()) { 1067 - case DrydockRepositoryOperation::STATE_WAIT: 1068 - case DrydockRepositoryOperation::STATE_WORK: 1069 - $severity = PHUIInfoView::SEVERITY_NOTICE; 1070 - $text = pht( 1071 - 'Some sort of repository operation is currently running.'); 1072 - break; 1073 - default: 1074 - $severity = PHUIInfoView::SEVERITY_ERROR; 1075 - $text = pht( 1076 - 'Some sort of repository operation failed.'); 1077 - break; 1078 - } 1079 - 1080 - $info_view = id(new PHUIInfoView()) 1081 - ->setSeverity($severity) 1082 - ->appendChild($text); 1083 - 1084 - return id(new PHUIObjectBoxView()) 1085 - ->setHeaderText(pht('Active Operations (EXPERIMENTAL!)')) 1086 - ->setInfoView($info_view); 1066 + return id(new DrydockRepositoryOperationStatusView()) 1067 + ->setUser($viewer) 1068 + ->setBoxView($box_view) 1069 + ->setOperation($operation); 1087 1070 } 1088 1071 1089 1072 }
+1
src/applications/drydock/application/PhabricatorDrydockApplication.php
··· 95 95 => 'DrydockRepositoryOperationListController', 96 96 '(?P<id>[1-9]\d*)/' => array( 97 97 '' => 'DrydockRepositoryOperationViewController', 98 + 'status/' => 'DrydockRepositoryOperationStatusController', 98 99 ), 99 100 ), 100 101 ),
+59
src/applications/drydock/controller/DrydockRepositoryOperationStatusController.php
··· 1 + <?php 2 + 3 + final class DrydockRepositoryOperationStatusController 4 + extends DrydockController { 5 + 6 + public function shouldAllowPublic() { 7 + return true; 8 + } 9 + 10 + public function handleRequest(AphrontRequest $request) { 11 + $viewer = $request->getViewer(); 12 + $id = $request->getURIData('id'); 13 + 14 + $operation = id(new DrydockRepositoryOperationQuery()) 15 + ->setViewer($viewer) 16 + ->withIDs(array($id)) 17 + ->executeOne(); 18 + if (!$operation) { 19 + return new Aphront404Response(); 20 + } 21 + 22 + $id = $operation->getID(); 23 + 24 + $status_view = id(new DrydockRepositoryOperationStatusView()) 25 + ->setUser($viewer) 26 + ->setOperation($operation); 27 + 28 + if ($request->isAjax()) { 29 + $payload = array( 30 + 'markup' => $status_view->renderUnderwayState(), 31 + 'isUnderway' => $operation->isUnderway(), 32 + ); 33 + 34 + return id(new AphrontAjaxResponse()) 35 + ->setContent($payload); 36 + } 37 + 38 + $title = pht('Repository Operation %d', $id); 39 + 40 + $crumbs = $this->buildApplicationCrumbs(); 41 + $crumbs->addTextCrumb( 42 + pht('Operations'), 43 + $this->getApplicationURI('operation/')); 44 + $crumbs->addTextCrumb($title); 45 + 46 + return $this->buildApplicationPage( 47 + array( 48 + $crumbs, 49 + $status_view, 50 + ), 51 + array( 52 + 'title' => array( 53 + $title, 54 + pht('Status'), 55 + ), 56 + )); 57 + } 58 + 59 + }
+24
src/applications/drydock/operation/DrydockLandRepositoryOperation.php
··· 11 11 return pht('Land Revision'); 12 12 } 13 13 14 + public function getOperationCurrentStatus( 15 + DrydockRepositoryOperation $operation, 16 + PhabricatorUser $viewer) { 17 + 18 + $target = $operation->getRepositoryTarget(); 19 + $repository = $operation->getRepository(); 20 + switch ($operation->getOperationState()) { 21 + case DrydockRepositoryOperation::STATE_WAIT: 22 + return pht( 23 + 'Waiting to land revision into %s on %s...', 24 + $repository->getMonogram(), 25 + $target); 26 + case DrydockRepositoryOperation::STATE_WORK: 27 + return pht( 28 + 'Landing revision into %s on %s...', 29 + $repository->getMonogram(), 30 + $target); 31 + case DrydockRepositoryOperation::STATE_DONE: 32 + return pht( 33 + 'Revision landed into %s.', 34 + $repository->getMonogram()); 35 + } 36 + } 37 + 14 38 public function applyOperation( 15 39 DrydockRepositoryOperation $operation, 16 40 DrydockInterface $interface) {
+4
src/applications/drydock/operation/DrydockRepositoryOperationType.php
··· 12 12 DrydockRepositoryOperation $operation, 13 13 PhabricatorUser $viewer); 14 14 15 + abstract public function getOperationCurrentStatus( 16 + DrydockRepositoryOperation $operation, 17 + PhabricatorUser $viewer); 18 + 15 19 final public function setViewer(PhabricatorUser $viewer) { 16 20 $this->viewer = $viewer; 17 21 return $this;
+16
src/applications/drydock/storage/DrydockRepositoryOperation.php
··· 142 142 $viewer); 143 143 } 144 144 145 + public function getOperationCurrentStatus(PhabricatorUser $viewer) { 146 + return $this->getImplementation()->getOperationCurrentStatus( 147 + $this, 148 + $viewer); 149 + } 150 + 151 + public function isUnderway() { 152 + switch ($this->getOperationState()) { 153 + case self::STATE_WAIT: 154 + case self::STATE_WORK: 155 + return true; 156 + } 157 + 158 + return false; 159 + } 160 + 145 161 146 162 /* -( PhabricatorPolicyInterface )----------------------------------------- */ 147 163
+84
src/applications/drydock/view/DrydockRepositoryOperationStatusView.php
··· 1 + <?php 2 + 3 + final class DrydockRepositoryOperationStatusView 4 + extends AphrontView { 5 + 6 + private $operation; 7 + private $boxView; 8 + 9 + public function setOperation(DrydockRepositoryOperation $operation) { 10 + $this->operation = $operation; 11 + return $this; 12 + } 13 + 14 + public function getOperation() { 15 + return $this->operation; 16 + } 17 + 18 + public function setBoxView(PHUIObjectBoxView $box_view) { 19 + $this->boxView = $box_view; 20 + return $this; 21 + } 22 + 23 + public function getBoxView() { 24 + return $this->boxView; 25 + } 26 + 27 + public function render() { 28 + $viewer = $this->getUser(); 29 + $operation = $this->getOperation(); 30 + 31 + $list = $this->renderUnderwayState(); 32 + 33 + // If the operation is currently underway, refresh the status view. 34 + if ($operation->isUnderway()) { 35 + $status_id = celerity_generate_unique_node_id(); 36 + $id = $operation->getID(); 37 + 38 + $list->setID($status_id); 39 + 40 + Javelin::initBehavior( 41 + 'drydock-live-operation-status', 42 + array( 43 + 'statusID' => $status_id, 44 + 'updateURI' => "/drydock/operation/{$id}/status/", 45 + )); 46 + } 47 + 48 + $box_view = $this->getBoxView(); 49 + if (!$box_view) { 50 + $box_view = id(new PHUIObjectBoxView()) 51 + ->setHeaderText(pht('Operation Status')); 52 + } 53 + $box_view->setObjectList($list); 54 + 55 + return $box_view; 56 + } 57 + 58 + public function renderUnderwayState() { 59 + $viewer = $this->getUser(); 60 + $operation = $this->getOperation(); 61 + 62 + $id = $operation->getID(); 63 + 64 + $state = $operation->getOperationState(); 65 + $icon = DrydockRepositoryOperation::getOperationStateIcon($state); 66 + $name = DrydockRepositoryOperation::getOperationStateName($state); 67 + 68 + $item = id(new PHUIObjectItemView()) 69 + ->setHref("/drydock/operation/{$id}/") 70 + ->setHeader($operation->getOperationDescription($viewer)) 71 + ->setStatusIcon($icon, $name); 72 + 73 + if ($state != DrydockRepositoryOperation::STATE_FAIL) { 74 + $item->addAttribute($operation->getOperationCurrentStatus($viewer)); 75 + } else { 76 + // TODO: Make this more useful. 77 + $item->addAttribute(pht('Operation encountered an error.')); 78 + } 79 + 80 + return id(new PHUIObjectItemListView()) 81 + ->addItem($item); 82 + } 83 + 84 + }
+32
webroot/rsrc/js/application/drydock/drydock-live-operation-status.js
··· 1 + /** 2 + * @provides javelin-behavior-drydock-live-operation-status 3 + * @requires javelin-behavior 4 + * javelin-dom 5 + * javelin-request 6 + * @javelin 7 + */ 8 + 9 + JX.behavior('drydock-live-operation-status', function(config) { 10 + var node = JX.$(config.statusID); 11 + 12 + function update() { 13 + new JX.Request(config.updateURI, onresponse) 14 + .send(); 15 + } 16 + 17 + function onresponse(r) { 18 + var new_node = JX.$H(r.markup).getNode(); 19 + JX.DOM.replace(node, new_node); 20 + node = new_node; 21 + 22 + if (r.isUnderway) { 23 + poll(); 24 + } 25 + } 26 + 27 + function poll() { 28 + setTimeout(update, 1000); 29 + } 30 + 31 + poll(); 32 + });