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 @@ -3416,6 +3416,7 @@ '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 @@ 'DrydockLeaseReleaseController' => 'DrydockLeaseController', 'DrydockLeaseReleasedLogType' => 'DrydockLogType', 'DrydockLeaseSearchEngine' => 'PhabricatorApplicationSearchEngine', - 'DrydockLeaseStatus' => 'DrydockConstants', + 'DrydockLeaseStatus' => 'PhabricatorObjectStatus', 'DrydockLeaseUpdateWorker' => 'DrydockWorker', 'DrydockLeaseViewController' => 'DrydockLeaseController', 'DrydockLeaseWaitingForResourcesLogType' => 'DrydockLogType', @@ -8994,6 +8995,7 @@ 'PhabricatorObjectRelationshipSource' => 'Phobject', 'PhabricatorObjectRemarkupRule' => 'PhutilRemarkupRule', 'PhabricatorObjectSelectorDialog' => 'Phobject', + 'PhabricatorObjectStatus' => 'Phobject', 'PhabricatorOffsetPagedQuery' => 'PhabricatorQuery', 'PhabricatorOldWorldContentSource' => 'PhabricatorContentSource', 'PhabricatorOlderInlinesSetting' => 'PhabricatorSelectSetting', diff --git a/src/applications/drydock/constants/DrydockLeaseStatus.php b/src/applications/drydock/constants/DrydockLeaseStatus.php --- a/src/applications/drydock/constants/DrydockLeaseStatus.php +++ b/src/applications/drydock/constants/DrydockLeaseStatus.php @@ -1,6 +1,7 @@ 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, + ); } } diff --git a/src/applications/drydock/controller/DrydockLeaseViewController.php b/src/applications/drydock/controller/DrydockLeaseViewController.php --- a/src/applications/drydock/controller/DrydockLeaseViewController.php +++ b/src/applications/drydock/controller/DrydockLeaseViewController.php @@ -22,10 +22,19 @@ $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 @@ $view = new PHUIPropertyListView(); - $view->addProperty( - pht('Status'), - DrydockLeaseStatus::getNameForStatus($lease->getStatus())); - $view->addProperty( pht('Resource Type'), $lease->getResourceType()); diff --git a/src/applications/drydock/storage/DrydockLease.php b/src/applications/drydock/storage/DrydockLease.php --- a/src/applications/drydock/storage/DrydockLease.php +++ b/src/applications/drydock/storage/DrydockLease.php @@ -175,25 +175,6 @@ 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 @@ 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 @@ } +/* -( 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 )----------------------------------------- */ diff --git a/src/applications/drydock/view/DrydockLeaseListView.php b/src/applications/drydock/view/DrydockLeaseListView.php --- a/src/applications/drydock/view/DrydockLeaseListView.php +++ b/src/applications/drydock/view/DrydockLeaseListView.php @@ -26,20 +26,20 @@ 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); } diff --git a/src/infrastructure/status/PhabricatorObjectStatus.php b/src/infrastructure/status/PhabricatorObjectStatus.php new file mode 100644 --- /dev/null +++ b/src/infrastructure/status/PhabricatorObjectStatus.php @@ -0,0 +1,84 @@ +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(); + } + +}