1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-22 14:52:41 +01:00

Give Drydock Leases more modern status treatment

Summary:
Depends on D19073. Ref T13073. Give leases a normal header tag and try to wrangle their status constants a bit.

Also, try to capture the "status class" pattern a bit. Since we target PHP 5.2.3 we can't use `static::` so the actual subclass is kind of a mess. Not exactly sure if I want to stick with this or not. We could consider targeting PHP 5.3.0 instead to get `static::` / late static binding.

Test Plan: Viewed leases and lease lists, saw better and more conventional status information.

Subscribers: PHID-OPKG-gm6ozazyms6q6i22gyam

Maniphest Tasks: T13073

Differential Revision: https://secure.phabricator.com/D19074
This commit is contained in:
epriestley 2018-02-13 04:55:23 -08:00
parent 07028cfc30
commit 27c3793d40
6 changed files with 242 additions and 72 deletions

View file

@ -3416,6 +3416,7 @@ phutil_register_library_map(array(
'PhabricatorObjectRelationshipSource' => 'applications/search/relationship/PhabricatorObjectRelationshipSource.php', 'PhabricatorObjectRelationshipSource' => 'applications/search/relationship/PhabricatorObjectRelationshipSource.php',
'PhabricatorObjectRemarkupRule' => 'infrastructure/markup/rule/PhabricatorObjectRemarkupRule.php', 'PhabricatorObjectRemarkupRule' => 'infrastructure/markup/rule/PhabricatorObjectRemarkupRule.php',
'PhabricatorObjectSelectorDialog' => 'view/control/PhabricatorObjectSelectorDialog.php', 'PhabricatorObjectSelectorDialog' => 'view/control/PhabricatorObjectSelectorDialog.php',
'PhabricatorObjectStatus' => 'infrastructure/status/PhabricatorObjectStatus.php',
'PhabricatorOffsetPagedQuery' => 'infrastructure/query/PhabricatorOffsetPagedQuery.php', 'PhabricatorOffsetPagedQuery' => 'infrastructure/query/PhabricatorOffsetPagedQuery.php',
'PhabricatorOldWorldContentSource' => 'infrastructure/contentsource/PhabricatorOldWorldContentSource.php', 'PhabricatorOldWorldContentSource' => 'infrastructure/contentsource/PhabricatorOldWorldContentSource.php',
'PhabricatorOlderInlinesSetting' => 'applications/settings/setting/PhabricatorOlderInlinesSetting.php', 'PhabricatorOlderInlinesSetting' => 'applications/settings/setting/PhabricatorOlderInlinesSetting.php',
@ -6290,7 +6291,7 @@ phutil_register_library_map(array(
'DrydockLeaseReleaseController' => 'DrydockLeaseController', 'DrydockLeaseReleaseController' => 'DrydockLeaseController',
'DrydockLeaseReleasedLogType' => 'DrydockLogType', 'DrydockLeaseReleasedLogType' => 'DrydockLogType',
'DrydockLeaseSearchEngine' => 'PhabricatorApplicationSearchEngine', 'DrydockLeaseSearchEngine' => 'PhabricatorApplicationSearchEngine',
'DrydockLeaseStatus' => 'DrydockConstants', 'DrydockLeaseStatus' => 'PhabricatorObjectStatus',
'DrydockLeaseUpdateWorker' => 'DrydockWorker', 'DrydockLeaseUpdateWorker' => 'DrydockWorker',
'DrydockLeaseViewController' => 'DrydockLeaseController', 'DrydockLeaseViewController' => 'DrydockLeaseController',
'DrydockLeaseWaitingForResourcesLogType' => 'DrydockLogType', 'DrydockLeaseWaitingForResourcesLogType' => 'DrydockLogType',
@ -8994,6 +8995,7 @@ phutil_register_library_map(array(
'PhabricatorObjectRelationshipSource' => 'Phobject', 'PhabricatorObjectRelationshipSource' => 'Phobject',
'PhabricatorObjectRemarkupRule' => 'PhutilRemarkupRule', 'PhabricatorObjectRemarkupRule' => 'PhutilRemarkupRule',
'PhabricatorObjectSelectorDialog' => 'Phobject', 'PhabricatorObjectSelectorDialog' => 'Phobject',
'PhabricatorObjectStatus' => 'Phobject',
'PhabricatorOffsetPagedQuery' => 'PhabricatorQuery', 'PhabricatorOffsetPagedQuery' => 'PhabricatorQuery',
'PhabricatorOldWorldContentSource' => 'PhabricatorContentSource', 'PhabricatorOldWorldContentSource' => 'PhabricatorContentSource',
'PhabricatorOlderInlinesSetting' => 'PhabricatorSelectSetting', 'PhabricatorOlderInlinesSetting' => 'PhabricatorSelectSetting',

View file

@ -1,6 +1,7 @@
<?php <?php
final class DrydockLeaseStatus extends DrydockConstants { final class DrydockLeaseStatus
extends PhabricatorObjectStatus {
const STATUS_PENDING = 'pending'; const STATUS_PENDING = 'pending';
const STATUS_ACQUIRED = 'acquired'; const STATUS_ACQUIRED = 'acquired';
@ -9,24 +10,105 @@ final class DrydockLeaseStatus extends DrydockConstants {
const STATUS_BROKEN = 'broken'; const STATUS_BROKEN = 'broken';
const STATUS_DESTROYED = 'destroyed'; const STATUS_DESTROYED = 'destroyed';
public static function newStatusObject($key) {
return new self($key, id(new self())->getStatusSpecification($key));
}
public static function getStatusMap() { public static function getStatusMap() {
return array( $map = id(new self())->getStatusSpecifications();
self::STATUS_PENDING => pht('Pending'), return ipull($map, 'name', 'key');
self::STATUS_ACQUIRED => pht('Acquired'),
self::STATUS_ACTIVE => pht('Active'),
self::STATUS_RELEASED => pht('Released'),
self::STATUS_BROKEN => pht('Broken'),
self::STATUS_DESTROYED => pht('Destroyed'),
);
} }
public static function getNameForStatus($status) { public static function getNameForStatus($status) {
$map = self::getStatusMap(); $map = id(new self())->getStatusSpecification($status);
return idx($map, $status, pht('Unknown')); return $map['name'];
} }
public static function getAllStatuses() { public static function getAllStatuses() {
return array_keys(self::getStatusMap()); return array_keys(id(new self())->getStatusSpecifications());
}
public function isActivating() {
return $this->getStatusProperty('isActivating');
}
public function isActive() {
return ($this->getKey() === self::STATUS_ACTIVE);
}
public function canRelease() {
return $this->getStatusProperty('isReleasable');
}
public function canReceiveCommands() {
return $this->getStatusProperty('isCommandable');
}
protected function newStatusSpecifications() {
return array(
array(
'key' => self::STATUS_PENDING,
'name' => pht('Pending'),
'icon' => 'fa-clock-o',
'color' => 'blue',
'isReleasable' => true,
'isCommandable' => true,
'isActivating' => true,
),
array(
'key' => self::STATUS_ACQUIRED,
'name' => pht('Acquired'),
'icon' => 'fa-refresh',
'color' => 'blue',
'isReleasable' => true,
'isCommandable' => true,
'isActivating' => true,
),
array(
'key' => self::STATUS_ACTIVE,
'name' => pht('Active'),
'icon' => 'fa-check',
'color' => 'green',
'isReleasable' => true,
'isCommandable' => true,
'isActivating' => false,
),
array(
'key' => self::STATUS_RELEASED,
'name' => pht('Released'),
'icon' => 'fa-circle-o',
'color' => 'blue',
'isReleasable' => false,
'isCommandable' => false,
'isActivating' => false,
),
array(
'key' => self::STATUS_BROKEN,
'name' => pht('Broken'),
'icon' => 'fa-times',
'color' => 'indigo',
'isReleasable' => true,
'isCommandable' => true,
'isActivating' => false,
),
array(
'key' => self::STATUS_DESTROYED,
'name' => pht('Destroyed'),
'icon' => 'fa-times',
'color' => 'red',
'isReleasable' => false,
'isCommandable' => false,
'isActivating' => false,
),
);
}
protected function newUnknownStatusSpecification($status) {
return array(
'isReleasable' => false,
'isCommandable' => false,
'isActivating' => false,
);
} }
} }

View file

@ -22,10 +22,19 @@ final class DrydockLeaseViewController extends DrydockLeaseController {
$header = id(new PHUIHeaderView()) $header = id(new PHUIHeaderView())
->setHeader($title) ->setHeader($title)
->setHeaderIcon('fa-link'); ->setHeaderIcon('fa-link')
->setStatus(
$lease->getStatusIcon(),
$lease->getStatusColor(),
$lease->getStatusDisplayName());
if ($lease->isReleasing()) { if ($lease->isReleasing()) {
$header->setStatus('fa-exclamation-triangle', 'red', pht('Releasing')); $header->addTag(
id(new PHUITagView())
->setType(PHUITagView::TYPE_SHADE)
->setIcon('fa-exclamation-triangle')
->setColor('red')
->setName('Releasing'));
} }
$curtain = $this->buildCurtain($lease); $curtain = $this->buildCurtain($lease);
@ -118,10 +127,6 @@ final class DrydockLeaseViewController extends DrydockLeaseController {
$view = new PHUIPropertyListView(); $view = new PHUIPropertyListView();
$view->addProperty(
pht('Status'),
DrydockLeaseStatus::getNameForStatus($lease->getStatus()));
$view->addProperty( $view->addProperty(
pht('Resource Type'), pht('Resource Type'),
$lease->getResourceType()); $lease->getResourceType());

View file

@ -175,25 +175,6 @@ final class DrydockLease extends DrydockDAO
return $this; return $this;
} }
public function isActivating() {
switch ($this->getStatus()) {
case DrydockLeaseStatus::STATUS_PENDING:
case DrydockLeaseStatus::STATUS_ACQUIRED:
return true;
}
return false;
}
public function isActive() {
switch ($this->getStatus()) {
case DrydockLeaseStatus::STATUS_ACTIVE:
return true;
}
return false;
}
public function setActivateWhenAcquired($activate) { public function setActivateWhenAcquired($activate) {
$this->activateWhenAcquired = true; $this->activateWhenAcquired = true;
return $this; return $this;
@ -325,30 +306,6 @@ final class DrydockLease extends DrydockDAO
return $this->isActivated; return $this->isActivated;
} }
public function canRelease() {
if (!$this->getID()) {
return false;
}
switch ($this->getStatus()) {
case DrydockLeaseStatus::STATUS_RELEASED:
case DrydockLeaseStatus::STATUS_DESTROYED:
return false;
default:
return true;
}
}
public function canReceiveCommands() {
switch ($this->getStatus()) {
case DrydockLeaseStatus::STATUS_RELEASED:
case DrydockLeaseStatus::STATUS_DESTROYED:
return false;
default:
return true;
}
}
public function scheduleUpdate($epoch = null) { public function scheduleUpdate($epoch = null) {
PhabricatorWorker::scheduleTask( PhabricatorWorker::scheduleTask(
'DrydockLeaseUpdateWorker', 'DrydockLeaseUpdateWorker',
@ -442,6 +399,46 @@ final class DrydockLease extends DrydockDAO
} }
/* -( Status )------------------------------------------------------------- */
public function getStatusObject() {
return DrydockLeaseStatus::newStatusObject($this->getStatus());
}
public function getStatusIcon() {
return $this->getStatusObject()->getIcon();
}
public function getStatusColor() {
return $this->getStatusObject()->getColor();
}
public function getStatusDisplayName() {
return $this->getStatusObject()->getDisplayName();
}
public function isActivating() {
return $this->getStatusObject()->isActivating();
}
public function isActive() {
return $this->getStatusObject()->isActive();
}
public function canRelease() {
if (!$this->getID()) {
return false;
}
return $this->getStatusObject()->canRelease();
}
public function canReceiveCommands() {
return $this->getStatusObject()->canReceiveCommands();
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */ /* -( PhabricatorPolicyInterface )----------------------------------------- */

View file

@ -26,20 +26,20 @@ final class DrydockLeaseListView extends AphrontView {
if ($resource_phid) { if ($resource_phid) {
$item->addAttribute( $item->addAttribute(
$viewer->renderHandle($resource_phid)); $viewer->renderHandle($resource_phid));
} else {
$item->addAttribute(
pht(
'Resource: %s',
$lease->getResourceType()));
} }
$status = DrydockLeaseStatus::getNameForStatus($lease->getStatus());
$item->addAttribute($status);
$item->setEpoch($lease->getDateCreated()); $item->setEpoch($lease->getDateCreated());
// TODO: Tailor this for clarity. $icon = $lease->getStatusIcon();
if ($lease->isActivating()) { $color = $lease->getStatusColor();
$item->setStatusIcon('fa-dot-circle-o yellow'); $label = $lease->getStatusDisplayName();
} else if ($lease->isActive()) {
$item->setStatusIcon('fa-dot-circle-o green'); $item->setStatusIcon("{$icon} {$color}", $label);
} else {
$item->setStatusIcon('fa-dot-circle-o red');
}
$view->addItem($item); $view->addItem($item);
} }

View file

@ -0,0 +1,84 @@
<?php
abstract class PhabricatorObjectStatus
extends Phobject {
private $key;
private $properties;
protected function __construct($key = null, array $properties = array()) {
$this->key = $key;
$this->properties = $properties;
}
protected function getStatusProperty($key) {
if (!array_key_exists($key, $this->properties)) {
throw new Exception(
pht(
'Attempting to access unknown status property ("%s").',
$key));
}
return $this->properties[$key];
}
public function getKey() {
return $this->key;
}
public function getIcon() {
return $this->getStatusProperty('icon');
}
public function getDisplayName() {
return $this->getStatusProperty('name');
}
public function getColor() {
return $this->getStatusProperty('color');
}
protected function getStatusSpecification($status) {
$map = self::getStatusSpecifications();
if (isset($map[$status])) {
return $map[$status];
}
return array(
'key' => $status,
'name' => pht('Unknown ("%s")', $status),
'icon' => 'fa-question-circle',
'color' => 'indigo',
) + $this->newUnknownStatusSpecification($status);
}
protected function getStatusSpecifications() {
$map = $this->newStatusSpecifications();
$result = array();
foreach ($map as $item) {
if (!array_key_exists('key', $item)) {
throw new Exception(pht('Status specification has no "key".'));
}
$key = $item['key'];
if (isset($result[$key])) {
throw new Exception(
pht(
'Multiple status definitions share the same key ("%s").',
$key));
}
$result[$key] = $item;
}
return $result;
}
abstract protected function newStatusSpecifications();
protected function newUnknownStatusSpecification($status) {
return array();
}
}