1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-18 12:52:42 +01:00

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
This commit is contained in:
epriestley 2015-10-21 11:28:26 -07:00
parent 421c2453e5
commit 5b619862cb
10 changed files with 237 additions and 23 deletions

View file

@ -373,6 +373,7 @@ return array(
'rsrc/js/application/diffusion/behavior-locate-file.js' => '6d3e1947',
'rsrc/js/application/diffusion/behavior-pull-lastmodified.js' => 'f01586dc',
'rsrc/js/application/doorkeeper/behavior-doorkeeper-tag.js' => 'e5822781',
'rsrc/js/application/drydock/drydock-live-operation-status.js' => '901935ef',
'rsrc/js/application/files/behavior-icon-composer.js' => '8ef9ab58',
'rsrc/js/application/files/behavior-launch-icon-composer.js' => '48086888',
'rsrc/js/application/herald/HeraldRuleEditor.js' => '91a6031b',
@ -576,6 +577,7 @@ return array(
'javelin-behavior-diffusion-locate-file' => '6d3e1947',
'javelin-behavior-diffusion-pull-lastmodified' => 'f01586dc',
'javelin-behavior-doorkeeper-tag' => 'e5822781',
'javelin-behavior-drydock-live-operation-status' => '901935ef',
'javelin-behavior-durable-column' => 'c72aa091',
'javelin-behavior-error-log' => '6882e80a',
'javelin-behavior-event-all-day' => '38dcf3c8',
@ -1518,6 +1520,11 @@ return array(
'javelin-dom',
'javelin-stratcom',
),
'901935ef' => array(
'javelin-behavior',
'javelin-dom',
'javelin-request',
),
'91a6031b' => array(
'multirow-row-manager',
'javelin-install',

View file

@ -885,6 +885,8 @@ phutil_register_library_map(array(
'DrydockRepositoryOperationPHIDType' => 'applications/drydock/phid/DrydockRepositoryOperationPHIDType.php',
'DrydockRepositoryOperationQuery' => 'applications/drydock/query/DrydockRepositoryOperationQuery.php',
'DrydockRepositoryOperationSearchEngine' => 'applications/drydock/query/DrydockRepositoryOperationSearchEngine.php',
'DrydockRepositoryOperationStatusController' => 'applications/drydock/controller/DrydockRepositoryOperationStatusController.php',
'DrydockRepositoryOperationStatusView' => 'applications/drydock/view/DrydockRepositoryOperationStatusView.php',
'DrydockRepositoryOperationType' => 'applications/drydock/operation/DrydockRepositoryOperationType.php',
'DrydockRepositoryOperationUpdateWorker' => 'applications/drydock/worker/DrydockRepositoryOperationUpdateWorker.php',
'DrydockRepositoryOperationViewController' => 'applications/drydock/controller/DrydockRepositoryOperationViewController.php',
@ -4672,6 +4674,8 @@ phutil_register_library_map(array(
'DrydockRepositoryOperationPHIDType' => 'PhabricatorPHIDType',
'DrydockRepositoryOperationQuery' => 'DrydockQuery',
'DrydockRepositoryOperationSearchEngine' => 'PhabricatorApplicationSearchEngine',
'DrydockRepositoryOperationStatusController' => 'DrydockController',
'DrydockRepositoryOperationStatusView' => 'AphrontView',
'DrydockRepositoryOperationType' => 'Phobject',
'DrydockRepositoryOperationUpdateWorker' => 'DrydockWorker',
'DrydockRepositoryOperationViewController' => 'DrydockController',

View file

@ -1060,30 +1060,13 @@ final class DifferentialRevisionViewController extends DifferentialController {
$operation = head(msort($operations, 'getID'));
// TODO: This is completely made up for now, give it useful information and
// a sweet progress bar.
$box_view = id(new PHUIObjectBoxView())
->setHeaderText(pht('Active Operations'));
switch ($operation->getOperationState()) {
case DrydockRepositoryOperation::STATE_WAIT:
case DrydockRepositoryOperation::STATE_WORK:
$severity = PHUIInfoView::SEVERITY_NOTICE;
$text = pht(
'Some sort of repository operation is currently running.');
break;
default:
$severity = PHUIInfoView::SEVERITY_ERROR;
$text = pht(
'Some sort of repository operation failed.');
break;
}
$info_view = id(new PHUIInfoView())
->setSeverity($severity)
->appendChild($text);
return id(new PHUIObjectBoxView())
->setHeaderText(pht('Active Operations (EXPERIMENTAL!)'))
->setInfoView($info_view);
return id(new DrydockRepositoryOperationStatusView())
->setUser($viewer)
->setBoxView($box_view)
->setOperation($operation);
}
}

View file

@ -95,6 +95,7 @@ final class PhabricatorDrydockApplication extends PhabricatorApplication {
=> 'DrydockRepositoryOperationListController',
'(?P<id>[1-9]\d*)/' => array(
'' => 'DrydockRepositoryOperationViewController',
'status/' => 'DrydockRepositoryOperationStatusController',
),
),
),

View file

@ -0,0 +1,59 @@
<?php
final class DrydockRepositoryOperationStatusController
extends DrydockController {
public function shouldAllowPublic() {
return true;
}
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
$operation = id(new DrydockRepositoryOperationQuery())
->setViewer($viewer)
->withIDs(array($id))
->executeOne();
if (!$operation) {
return new Aphront404Response();
}
$id = $operation->getID();
$status_view = id(new DrydockRepositoryOperationStatusView())
->setUser($viewer)
->setOperation($operation);
if ($request->isAjax()) {
$payload = array(
'markup' => $status_view->renderUnderwayState(),
'isUnderway' => $operation->isUnderway(),
);
return id(new AphrontAjaxResponse())
->setContent($payload);
}
$title = pht('Repository Operation %d', $id);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(
pht('Operations'),
$this->getApplicationURI('operation/'));
$crumbs->addTextCrumb($title);
return $this->buildApplicationPage(
array(
$crumbs,
$status_view,
),
array(
'title' => array(
$title,
pht('Status'),
),
));
}
}

View file

@ -11,6 +11,30 @@ final class DrydockLandRepositoryOperation
return pht('Land Revision');
}
public function getOperationCurrentStatus(
DrydockRepositoryOperation $operation,
PhabricatorUser $viewer) {
$target = $operation->getRepositoryTarget();
$repository = $operation->getRepository();
switch ($operation->getOperationState()) {
case DrydockRepositoryOperation::STATE_WAIT:
return pht(
'Waiting to land revision into %s on %s...',
$repository->getMonogram(),
$target);
case DrydockRepositoryOperation::STATE_WORK:
return pht(
'Landing revision into %s on %s...',
$repository->getMonogram(),
$target);
case DrydockRepositoryOperation::STATE_DONE:
return pht(
'Revision landed into %s.',
$repository->getMonogram());
}
}
public function applyOperation(
DrydockRepositoryOperation $operation,
DrydockInterface $interface) {

View file

@ -12,6 +12,10 @@ abstract class DrydockRepositoryOperationType extends Phobject {
DrydockRepositoryOperation $operation,
PhabricatorUser $viewer);
abstract public function getOperationCurrentStatus(
DrydockRepositoryOperation $operation,
PhabricatorUser $viewer);
final public function setViewer(PhabricatorUser $viewer) {
$this->viewer = $viewer;
return $this;

View file

@ -142,6 +142,22 @@ final class DrydockRepositoryOperation extends DrydockDAO
$viewer);
}
public function getOperationCurrentStatus(PhabricatorUser $viewer) {
return $this->getImplementation()->getOperationCurrentStatus(
$this,
$viewer);
}
public function isUnderway() {
switch ($this->getOperationState()) {
case self::STATE_WAIT:
case self::STATE_WORK:
return true;
}
return false;
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */

View file

@ -0,0 +1,84 @@
<?php
final class DrydockRepositoryOperationStatusView
extends AphrontView {
private $operation;
private $boxView;
public function setOperation(DrydockRepositoryOperation $operation) {
$this->operation = $operation;
return $this;
}
public function getOperation() {
return $this->operation;
}
public function setBoxView(PHUIObjectBoxView $box_view) {
$this->boxView = $box_view;
return $this;
}
public function getBoxView() {
return $this->boxView;
}
public function render() {
$viewer = $this->getUser();
$operation = $this->getOperation();
$list = $this->renderUnderwayState();
// If the operation is currently underway, refresh the status view.
if ($operation->isUnderway()) {
$status_id = celerity_generate_unique_node_id();
$id = $operation->getID();
$list->setID($status_id);
Javelin::initBehavior(
'drydock-live-operation-status',
array(
'statusID' => $status_id,
'updateURI' => "/drydock/operation/{$id}/status/",
));
}
$box_view = $this->getBoxView();
if (!$box_view) {
$box_view = id(new PHUIObjectBoxView())
->setHeaderText(pht('Operation Status'));
}
$box_view->setObjectList($list);
return $box_view;
}
public function renderUnderwayState() {
$viewer = $this->getUser();
$operation = $this->getOperation();
$id = $operation->getID();
$state = $operation->getOperationState();
$icon = DrydockRepositoryOperation::getOperationStateIcon($state);
$name = DrydockRepositoryOperation::getOperationStateName($state);
$item = id(new PHUIObjectItemView())
->setHref("/drydock/operation/{$id}/")
->setHeader($operation->getOperationDescription($viewer))
->setStatusIcon($icon, $name);
if ($state != DrydockRepositoryOperation::STATE_FAIL) {
$item->addAttribute($operation->getOperationCurrentStatus($viewer));
} else {
// TODO: Make this more useful.
$item->addAttribute(pht('Operation encountered an error.'));
}
return id(new PHUIObjectItemListView())
->addItem($item);
}
}

View file

@ -0,0 +1,32 @@
/**
* @provides javelin-behavior-drydock-live-operation-status
* @requires javelin-behavior
* javelin-dom
* javelin-request
* @javelin
*/
JX.behavior('drydock-live-operation-status', function(config) {
var node = JX.$(config.statusID);
function update() {
new JX.Request(config.updateURI, onresponse)
.send();
}
function onresponse(r) {
var new_node = JX.$H(r.markup).getNode();
JX.DOM.replace(node, new_node);
node = new_node;
if (r.isUnderway) {
poll();
}
}
function poll() {
setTimeout(update, 1000);
}
poll();
});