mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 06:42:42 +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:
parent
07028cfc30
commit
27c3793d40
6 changed files with 242 additions and 72 deletions
|
@ -3416,6 +3416,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorObjectRelationshipSource' => 'applications/search/relationship/PhabricatorObjectRelationshipSource.php',
|
||||
'PhabricatorObjectRemarkupRule' => 'infrastructure/markup/rule/PhabricatorObjectRemarkupRule.php',
|
||||
'PhabricatorObjectSelectorDialog' => 'view/control/PhabricatorObjectSelectorDialog.php',
|
||||
'PhabricatorObjectStatus' => 'infrastructure/status/PhabricatorObjectStatus.php',
|
||||
'PhabricatorOffsetPagedQuery' => 'infrastructure/query/PhabricatorOffsetPagedQuery.php',
|
||||
'PhabricatorOldWorldContentSource' => 'infrastructure/contentsource/PhabricatorOldWorldContentSource.php',
|
||||
'PhabricatorOlderInlinesSetting' => 'applications/settings/setting/PhabricatorOlderInlinesSetting.php',
|
||||
|
@ -6290,7 +6291,7 @@ phutil_register_library_map(array(
|
|||
'DrydockLeaseReleaseController' => 'DrydockLeaseController',
|
||||
'DrydockLeaseReleasedLogType' => 'DrydockLogType',
|
||||
'DrydockLeaseSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'DrydockLeaseStatus' => 'DrydockConstants',
|
||||
'DrydockLeaseStatus' => 'PhabricatorObjectStatus',
|
||||
'DrydockLeaseUpdateWorker' => 'DrydockWorker',
|
||||
'DrydockLeaseViewController' => 'DrydockLeaseController',
|
||||
'DrydockLeaseWaitingForResourcesLogType' => 'DrydockLogType',
|
||||
|
@ -8994,6 +8995,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorObjectRelationshipSource' => 'Phobject',
|
||||
'PhabricatorObjectRemarkupRule' => 'PhutilRemarkupRule',
|
||||
'PhabricatorObjectSelectorDialog' => 'Phobject',
|
||||
'PhabricatorObjectStatus' => 'Phobject',
|
||||
'PhabricatorOffsetPagedQuery' => 'PhabricatorQuery',
|
||||
'PhabricatorOldWorldContentSource' => 'PhabricatorContentSource',
|
||||
'PhabricatorOlderInlinesSetting' => 'PhabricatorSelectSetting',
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
final class DrydockLeaseStatus extends DrydockConstants {
|
||||
final class DrydockLeaseStatus
|
||||
extends PhabricatorObjectStatus {
|
||||
|
||||
const STATUS_PENDING = 'pending';
|
||||
const STATUS_ACQUIRED = 'acquired';
|
||||
|
@ -9,24 +10,105 @@ final class DrydockLeaseStatus extends DrydockConstants {
|
|||
const STATUS_BROKEN = 'broken';
|
||||
const STATUS_DESTROYED = 'destroyed';
|
||||
|
||||
public static function newStatusObject($key) {
|
||||
return new self($key, id(new self())->getStatusSpecification($key));
|
||||
}
|
||||
|
||||
public static function getStatusMap() {
|
||||
return array(
|
||||
self::STATUS_PENDING => pht('Pending'),
|
||||
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'),
|
||||
);
|
||||
$map = id(new self())->getStatusSpecifications();
|
||||
return ipull($map, 'name', 'key');
|
||||
}
|
||||
|
||||
public static function getNameForStatus($status) {
|
||||
$map = self::getStatusMap();
|
||||
return idx($map, $status, pht('Unknown'));
|
||||
$map = id(new self())->getStatusSpecification($status);
|
||||
return $map['name'];
|
||||
}
|
||||
|
||||
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,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,10 +22,19 @@ final class DrydockLeaseViewController extends DrydockLeaseController {
|
|||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($title)
|
||||
->setHeaderIcon('fa-link');
|
||||
->setHeaderIcon('fa-link')
|
||||
->setStatus(
|
||||
$lease->getStatusIcon(),
|
||||
$lease->getStatusColor(),
|
||||
$lease->getStatusDisplayName());
|
||||
|
||||
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);
|
||||
|
@ -118,10 +127,6 @@ final class DrydockLeaseViewController extends DrydockLeaseController {
|
|||
|
||||
$view = new PHUIPropertyListView();
|
||||
|
||||
$view->addProperty(
|
||||
pht('Status'),
|
||||
DrydockLeaseStatus::getNameForStatus($lease->getStatus()));
|
||||
|
||||
$view->addProperty(
|
||||
pht('Resource Type'),
|
||||
$lease->getResourceType());
|
||||
|
|
|
@ -175,25 +175,6 @@ final class DrydockLease extends DrydockDAO
|
|||
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) {
|
||||
$this->activateWhenAcquired = true;
|
||||
return $this;
|
||||
|
@ -325,30 +306,6 @@ final class DrydockLease extends DrydockDAO
|
|||
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) {
|
||||
PhabricatorWorker::scheduleTask(
|
||||
'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 )----------------------------------------- */
|
||||
|
||||
|
||||
|
|
|
@ -26,20 +26,20 @@ final class DrydockLeaseListView extends AphrontView {
|
|||
if ($resource_phid) {
|
||||
$item->addAttribute(
|
||||
$viewer->renderHandle($resource_phid));
|
||||
} else {
|
||||
$item->addAttribute(
|
||||
pht(
|
||||
'Resource: %s',
|
||||
$lease->getResourceType()));
|
||||
}
|
||||
|
||||
$status = DrydockLeaseStatus::getNameForStatus($lease->getStatus());
|
||||
$item->addAttribute($status);
|
||||
$item->setEpoch($lease->getDateCreated());
|
||||
|
||||
// TODO: Tailor this for clarity.
|
||||
if ($lease->isActivating()) {
|
||||
$item->setStatusIcon('fa-dot-circle-o yellow');
|
||||
} else if ($lease->isActive()) {
|
||||
$item->setStatusIcon('fa-dot-circle-o green');
|
||||
} else {
|
||||
$item->setStatusIcon('fa-dot-circle-o red');
|
||||
}
|
||||
$icon = $lease->getStatusIcon();
|
||||
$color = $lease->getStatusColor();
|
||||
$label = $lease->getStatusDisplayName();
|
||||
|
||||
$item->setStatusIcon("{$icon} {$color}", $label);
|
||||
|
||||
$view->addItem($item);
|
||||
}
|
||||
|
|
84
src/infrastructure/status/PhabricatorObjectStatus.php
Normal file
84
src/infrastructure/status/PhabricatorObjectStatus.php
Normal 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();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue