Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15389285
D14314.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
12 KB
Referenced Files
None
Subscribers
None
D14314.id.diff
View Options
diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -373,6 +373,7 @@
'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 @@
'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 @@
'javelin-dom',
'javelin-stratcom',
),
+ '901935ef' => array(
+ 'javelin-behavior',
+ 'javelin-dom',
+ 'javelin-request',
+ ),
'91a6031b' => array(
'multirow-row-manager',
'javelin-install',
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -885,6 +885,8 @@
'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 @@
'DrydockRepositoryOperationPHIDType' => 'PhabricatorPHIDType',
'DrydockRepositoryOperationQuery' => 'DrydockQuery',
'DrydockRepositoryOperationSearchEngine' => 'PhabricatorApplicationSearchEngine',
+ 'DrydockRepositoryOperationStatusController' => 'DrydockController',
+ 'DrydockRepositoryOperationStatusView' => 'AphrontView',
'DrydockRepositoryOperationType' => 'Phobject',
'DrydockRepositoryOperationUpdateWorker' => 'DrydockWorker',
'DrydockRepositoryOperationViewController' => 'DrydockController',
diff --git a/src/applications/differential/controller/DifferentialRevisionViewController.php b/src/applications/differential/controller/DifferentialRevisionViewController.php
--- a/src/applications/differential/controller/DifferentialRevisionViewController.php
+++ b/src/applications/differential/controller/DifferentialRevisionViewController.php
@@ -1060,30 +1060,13 @@
$operation = head(msort($operations, 'getID'));
- // TODO: This is completely made up for now, give it useful information and
- // a sweet progress bar.
-
- 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);
+ $box_view = id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('Active Operations'));
- return id(new PHUIObjectBoxView())
- ->setHeaderText(pht('Active Operations (EXPERIMENTAL!)'))
- ->setInfoView($info_view);
+ return id(new DrydockRepositoryOperationStatusView())
+ ->setUser($viewer)
+ ->setBoxView($box_view)
+ ->setOperation($operation);
}
}
diff --git a/src/applications/drydock/application/PhabricatorDrydockApplication.php b/src/applications/drydock/application/PhabricatorDrydockApplication.php
--- a/src/applications/drydock/application/PhabricatorDrydockApplication.php
+++ b/src/applications/drydock/application/PhabricatorDrydockApplication.php
@@ -95,6 +95,7 @@
=> 'DrydockRepositoryOperationListController',
'(?P<id>[1-9]\d*)/' => array(
'' => 'DrydockRepositoryOperationViewController',
+ 'status/' => 'DrydockRepositoryOperationStatusController',
),
),
),
diff --git a/src/applications/drydock/controller/DrydockRepositoryOperationStatusController.php b/src/applications/drydock/controller/DrydockRepositoryOperationStatusController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/drydock/controller/DrydockRepositoryOperationStatusController.php
@@ -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'),
+ ),
+ ));
+ }
+
+}
diff --git a/src/applications/drydock/operation/DrydockLandRepositoryOperation.php b/src/applications/drydock/operation/DrydockLandRepositoryOperation.php
--- a/src/applications/drydock/operation/DrydockLandRepositoryOperation.php
+++ b/src/applications/drydock/operation/DrydockLandRepositoryOperation.php
@@ -11,6 +11,30 @@
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) {
diff --git a/src/applications/drydock/operation/DrydockRepositoryOperationType.php b/src/applications/drydock/operation/DrydockRepositoryOperationType.php
--- a/src/applications/drydock/operation/DrydockRepositoryOperationType.php
+++ b/src/applications/drydock/operation/DrydockRepositoryOperationType.php
@@ -12,6 +12,10 @@
DrydockRepositoryOperation $operation,
PhabricatorUser $viewer);
+ abstract public function getOperationCurrentStatus(
+ DrydockRepositoryOperation $operation,
+ PhabricatorUser $viewer);
+
final public function setViewer(PhabricatorUser $viewer) {
$this->viewer = $viewer;
return $this;
diff --git a/src/applications/drydock/storage/DrydockRepositoryOperation.php b/src/applications/drydock/storage/DrydockRepositoryOperation.php
--- a/src/applications/drydock/storage/DrydockRepositoryOperation.php
+++ b/src/applications/drydock/storage/DrydockRepositoryOperation.php
@@ -142,6 +142,22 @@
$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 )----------------------------------------- */
diff --git a/src/applications/drydock/view/DrydockRepositoryOperationStatusView.php b/src/applications/drydock/view/DrydockRepositoryOperationStatusView.php
new file mode 100644
--- /dev/null
+++ b/src/applications/drydock/view/DrydockRepositoryOperationStatusView.php
@@ -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);
+ }
+
+}
diff --git a/webroot/rsrc/js/application/drydock/drydock-live-operation-status.js b/webroot/rsrc/js/application/drydock/drydock-live-operation-status.js
new file mode 100644
--- /dev/null
+++ b/webroot/rsrc/js/application/drydock/drydock-live-operation-status.js
@@ -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();
+});
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mar 16 2025, 5:05 AM (4 w, 5 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7660866
Default Alt Text
D14314.id.diff (12 KB)
Attached To
Mode
D14314: Show a more reasonable status element for pull requests
Attached
Detach File
Event Timeline
Log In to Comment