Page MenuHomePhorge

No OneTemporary

diff --git a/src/applications/drydock/application/PhabricatorDrydockApplication.php b/src/applications/drydock/application/PhabricatorDrydockApplication.php
index bf95a57009..5df54593ee 100644
--- a/src/applications/drydock/application/PhabricatorDrydockApplication.php
+++ b/src/applications/drydock/application/PhabricatorDrydockApplication.php
@@ -1,100 +1,102 @@
<?php
final class PhabricatorDrydockApplication extends PhabricatorApplication {
public function getBaseURI() {
return '/drydock/';
}
public function getName() {
return pht('Drydock');
}
public function getShortDescription() {
return pht('Allocate Software Resources');
}
public function getFontIcon() {
return 'fa-truck';
}
public function getTitleGlyph() {
return "\xE2\x98\x82";
}
public function getFlavorText() {
return pht('A nautical adventure.');
}
public function getApplicationGroup() {
return self::GROUP_UTILITIES;
}
public function isPrototype() {
return true;
}
public function getHelpDocumentationArticles(PhabricatorUser $viewer) {
return array(
array(
'name' => pht('Drydock User Guide'),
'href' => PhabricatorEnv::getDoclink('Drydock User Guide'),
),
);
}
public function getRoutes() {
return array(
'/drydock/' => array(
'' => 'DrydockConsoleController',
'blueprint/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' => 'DrydockBlueprintListController',
'(?P<id>[1-9]\d*)/' => array(
'' => 'DrydockBlueprintViewController',
'(?P<action>disable|enable)/' =>
'DrydockBlueprintDisableController',
'resources/(?:query/(?P<queryKey>[^/]+)/)?' =>
'DrydockResourceListController',
),
'create/' => 'DrydockBlueprintCreateController',
'edit/(?:(?P<id>[1-9]\d*)/)?' => 'DrydockBlueprintEditController',
),
'resource/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' => 'DrydockResourceListController',
'(?P<id>[1-9]\d*)/' => array(
'' => 'DrydockResourceViewController',
'release/' => 'DrydockResourceReleaseController',
+ 'leases/(?:query/(?P<queryKey>[^/]+)/)?' =>
+ 'DrydockLeaseListController',
),
),
'lease/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' => 'DrydockLeaseListController',
'(?P<id>[1-9]\d*)/' => array(
'' => 'DrydockLeaseViewController',
'release/' => 'DrydockLeaseReleaseController',
),
),
'log/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' => 'DrydockLogListController',
),
),
);
}
protected function getCustomCapabilities() {
return array(
DrydockDefaultViewCapability::CAPABILITY => array(
'template' => DrydockBlueprintPHIDType::TYPECONST,
'capability' => PhabricatorPolicyCapability::CAN_VIEW,
),
DrydockDefaultEditCapability::CAPABILITY => array(
'default' => PhabricatorPolicies::POLICY_ADMIN,
'template' => DrydockBlueprintPHIDType::TYPECONST,
'capability' => PhabricatorPolicyCapability::CAN_EDIT,
),
DrydockCreateBlueprintsCapability::CAPABILITY => array(
'default' => PhabricatorPolicies::POLICY_ADMIN,
),
);
}
}
diff --git a/src/applications/drydock/controller/DrydockLeaseController.php b/src/applications/drydock/controller/DrydockLeaseController.php
index d520fc66ee..d5a6335454 100644
--- a/src/applications/drydock/controller/DrydockLeaseController.php
+++ b/src/applications/drydock/controller/DrydockLeaseController.php
@@ -1,27 +1,62 @@
<?php
abstract class DrydockLeaseController
extends DrydockController {
+ private $resource;
+
+ public function setResource($resource) {
+ $this->resource = $resource;
+ return $this;
+ }
+
+ public function getResource() {
+ return $this->resource;
+ }
+
public function buildSideNavView() {
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
- id(new DrydockLeaseSearchEngine())
- ->setViewer($this->getRequest()->getUser())
- ->addNavigationItems($nav->getMenu());
+ $engine = id(new DrydockLeaseSearchEngine())
+ ->setViewer($this->getRequest()->getUser());
+
+ if ($this->getResource()) {
+ $engine->setResource($this->getResource());
+ }
+
+ $engine->addNavigationItems($nav->getMenu());
$nav->selectFilter(null);
return $nav;
}
protected function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
- $crumbs->addTextCrumb(
- pht('Leases'),
- $this->getApplicationURI('lease/'));
+
+ $resource = $this->getResource();
+ if ($resource) {
+ $id = $resource->getID();
+
+ $crumbs->addTextCrumb(
+ pht('Resources'),
+ $this->getApplicationURI('resource/'));
+
+ $crumbs->addTextCrumb(
+ $resource->getName(),
+ $this->getApplicationURI("resource/{$id}/"));
+
+ $crumbs->addTextCrumb(
+ pht('Leases'),
+ $this->getApplicationURI("resource/{$id}/leases/"));
+
+ } else {
+ $crumbs->addTextCrumb(
+ pht('Leases'),
+ $this->getApplicationURI('lease/'));
+ }
return $crumbs;
}
}
diff --git a/src/applications/drydock/controller/DrydockLeaseListController.php b/src/applications/drydock/controller/DrydockLeaseListController.php
index e370467a5f..321e1d4ae7 100644
--- a/src/applications/drydock/controller/DrydockLeaseListController.php
+++ b/src/applications/drydock/controller/DrydockLeaseListController.php
@@ -1,21 +1,36 @@
<?php
final class DrydockLeaseListController extends DrydockLeaseController {
public function shouldAllowPublic() {
return true;
}
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
- $querykey = $request->getURIData('queryKey');
+ $query_key = $request->getURIData('queryKey');
+
+ $engine = new DrydockLeaseSearchEngine();
+
+ $id = $request->getURIData('id');
+ if ($id) {
+ $resource = id(new DrydockResourceQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($id))
+ ->executeOne();
+ if (!$resource) {
+ return new Aphront404Response();
+ }
+ $this->setResource($resource);
+ $engine->setResource($resource);
+ }
$controller = id(new PhabricatorApplicationSearchController())
- ->setQueryKey($querykey)
- ->setSearchEngine(new DrydockLeaseSearchEngine())
+ ->setQueryKey($query_key)
+ ->setSearchEngine($engine)
->setNavigation($this->buildSideNavView());
return $this->delegateToController($controller);
}
}
diff --git a/src/applications/drydock/controller/DrydockResourceController.php b/src/applications/drydock/controller/DrydockResourceController.php
index 8675b5bf59..120d6d7cb0 100644
--- a/src/applications/drydock/controller/DrydockResourceController.php
+++ b/src/applications/drydock/controller/DrydockResourceController.php
@@ -1,55 +1,60 @@
<?php
abstract class DrydockResourceController
extends DrydockController {
private $blueprint;
public function setBlueprint($blueprint) {
$this->blueprint = $blueprint;
return $this;
}
public function getBlueprint() {
return $this->blueprint;
}
public function buildSideNavView() {
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
- id(new DrydockResourceSearchEngine())
- ->setViewer($this->getViewer())
- ->addNavigationItems($nav->getMenu());
+ $engine = id(new DrydockResourceSearchEngine())
+ ->setViewer($this->getViewer());
+
+ if ($this->getBlueprint()) {
+ $engine->setBlueprint($this->getBlueprint());
+ }
+
+ $engine->addNavigationItems($nav->getMenu());
$nav->selectFilter(null);
return $nav;
}
protected function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$blueprint = $this->getBlueprint();
if ($blueprint) {
$id = $blueprint->getID();
$crumbs->addTextCrumb(
pht('Blueprints'),
$this->getApplicationURI('blueprint/'));
$crumbs->addTextCrumb(
$blueprint->getBlueprintName(),
$this->getApplicationURI("blueprint/{$id}/"));
$crumbs->addTextCrumb(
pht('Resources'),
$this->getApplicationURI("blueprint/{$id}/resources/"));
} else {
$crumbs->addTextCrumb(
pht('Resources'),
$this->getApplicationURI('resource/'));
}
return $crumbs;
}
}
diff --git a/src/applications/drydock/controller/DrydockResourceViewController.php b/src/applications/drydock/controller/DrydockResourceViewController.php
index be1db24a0c..0641ced96d 100644
--- a/src/applications/drydock/controller/DrydockResourceViewController.php
+++ b/src/applications/drydock/controller/DrydockResourceViewController.php
@@ -1,152 +1,178 @@
<?php
final class DrydockResourceViewController extends DrydockResourceController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
$resource = id(new DrydockResourceQuery())
->setViewer($viewer)
->withIDs(array($id))
->executeOne();
if (!$resource) {
return new Aphront404Response();
}
$title = pht('Resource %s %s', $resource->getID(), $resource->getName());
$header = id(new PHUIHeaderView())
->setUser($viewer)
->setPolicyObject($resource)
->setHeader($title);
$actions = $this->buildActionListView($resource);
$properties = $this->buildPropertyListView($resource, $actions);
$resource_uri = 'resource/'.$resource->getID().'/';
$resource_uri = $this->getApplicationURI($resource_uri);
- $leases = id(new DrydockLeaseQuery())
- ->setViewer($viewer)
- ->withResourcePHIDs(array($resource->getPHID()))
- ->execute();
-
- $lease_list = id(new DrydockLeaseListView())
- ->setUser($viewer)
- ->setLeases($leases)
- ->render();
- $lease_list->setNoDataString(pht('This resource has no leases.'));
-
$pager = new PHUIPagerView();
$pager->setURI(new PhutilURI($resource_uri), 'offset');
$pager->setOffset($request->getInt('offset'));
$logs = id(new DrydockLogQuery())
->setViewer($viewer)
->withResourceIDs(array($resource->getID()))
->executeWithOffsetPager($pager);
$log_table = id(new DrydockLogListView())
->setUser($viewer)
->setLogs($logs)
->render();
$log_table->appendChild($pager);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Resource %d', $resource->getID()));
$locks = $this->buildLocksTab($resource->getPHID());
$commands = $this->buildCommandsTab($resource->getPHID());
$object_box = id(new PHUIObjectBoxView())
->setHeader($header)
->addPropertyList($properties, pht('Properties'))
->addPropertyList($locks, pht('Slot Locks'))
->addPropertyList($commands, pht('Commands'));
- $lease_box = id(new PHUIObjectBoxView())
- ->setHeaderText(pht('Leases'))
- ->setObjectList($lease_list);
+ $lease_box = $this->buildLeaseBox($resource);
$log_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Resource Logs'))
->setTable($log_table);
return $this->buildApplicationPage(
array(
$crumbs,
$object_box,
$lease_box,
$log_box,
),
array(
'title' => $title,
));
}
private function buildActionListView(DrydockResource $resource) {
$viewer = $this->getViewer();
$view = id(new PhabricatorActionListView())
->setUser($viewer)
->setObjectURI($this->getRequest()->getRequestURI())
->setObject($resource);
$can_release = $resource->canRelease();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$resource,
PhabricatorPolicyCapability::CAN_EDIT);
$uri = '/resource/'.$resource->getID().'/release/';
$uri = $this->getApplicationURI($uri);
$view->addAction(
id(new PhabricatorActionView())
->setHref($uri)
->setName(pht('Release Resource'))
->setIcon('fa-times')
->setWorkflow(true)
->setDisabled(!$can_release || !$can_edit));
return $view;
}
private function buildPropertyListView(
DrydockResource $resource,
PhabricatorActionListView $actions) {
$viewer = $this->getViewer();
$view = id(new PHUIPropertyListView())
->setActionList($actions);
$status = $resource->getStatus();
$status = DrydockResourceStatus::getNameForStatus($status);
$view->addProperty(
pht('Status'),
$status);
$view->addProperty(
pht('Resource Type'),
$resource->getType());
$view->addProperty(
pht('Blueprint'),
$viewer->renderHandle($resource->getBlueprintPHID()));
$attributes = $resource->getAttributes();
if ($attributes) {
$view->addSectionHeader(
pht('Attributes'), 'fa-list-ul');
foreach ($attributes as $key => $value) {
$view->addProperty($key, $value);
}
}
return $view;
}
+ private function buildLeaseBox(DrydockResource $resource) {
+ $viewer = $this->getViewer();
+
+ $leases = id(new DrydockLeaseQuery())
+ ->setViewer($viewer)
+ ->withResourcePHIDs(array($resource->getPHID()))
+ ->withStatuses(
+ array(
+ DrydockLeaseStatus::STATUS_PENDING,
+ DrydockLeaseStatus::STATUS_ACQUIRED,
+ DrydockLeaseStatus::STATUS_ACTIVE,
+ ))
+ ->setLimit(100)
+ ->execute();
+
+ $id = $resource->getID();
+ $leases_uri = "resource/{$id}/leases/query/all/";
+ $leases_uri = $this->getApplicationURI($leases_uri);
+
+ $lease_header = id(new PHUIHeaderView())
+ ->setHeader(pht('Active Leases'))
+ ->addActionLink(
+ id(new PHUIButtonView())
+ ->setTag('a')
+ ->setHref($leases_uri)
+ ->setIconFont('fa-search')
+ ->setText(pht('View All Leases')));
+
+ $lease_list = id(new DrydockLeaseListView())
+ ->setUser($viewer)
+ ->setLeases($leases)
+ ->render()
+ ->setNoDataString(pht('This resource has no active leases.'));
+
+ return id(new PHUIObjectBoxView())
+ ->setHeader($lease_header)
+ ->setObjectList($lease_list);
+ }
+
}
diff --git a/src/applications/drydock/query/DrydockLeaseSearchEngine.php b/src/applications/drydock/query/DrydockLeaseSearchEngine.php
index 7d85ddbe70..3b551023b2 100644
--- a/src/applications/drydock/query/DrydockLeaseSearchEngine.php
+++ b/src/applications/drydock/query/DrydockLeaseSearchEngine.php
@@ -1,81 +1,105 @@
<?php
final class DrydockLeaseSearchEngine
extends PhabricatorApplicationSearchEngine {
+ private $resource;
+
+ public function setResource($resource) {
+ $this->resource = $resource;
+ return $this;
+ }
+
+ public function getResource() {
+ return $this->resource;
+ }
+
public function getResultTypeDescription() {
return pht('Drydock Leases');
}
public function getApplicationClassName() {
return 'PhabricatorDrydockApplication';
}
public function newQuery() {
- return new DrydockLeaseQuery();
+ $query = new DrydockLeaseQuery();
+
+ $resource = $this->getResource();
+ if ($resource) {
+ $query->withResourcePHIDs(array($resource->getPHID()));
+ }
+
+ return $query;
}
protected function buildQueryFromParameters(array $map) {
$query = $this->newQuery();
if ($map['statuses']) {
$query->withStatuses($map['statuses']);
}
return $query;
}
protected function buildCustomSearchFields() {
return array(
id(new PhabricatorSearchCheckboxesField())
->setLabel(pht('Statuses'))
->setKey('statuses')
->setOptions(DrydockLeaseStatus::getStatusMap()),
);
}
protected function getURI($path) {
- return '/drydock/lease/'.$path;
+ $resource = $this->getResource();
+ if ($resource) {
+ $id = $resource->getID();
+ return "/drydock/resource/{$id}/leases/".$path;
+ } else {
+ return '/drydock/lease/'.$path;
+ }
}
protected function getBuiltinQueryNames() {
return array(
'active' => pht('Active Leases'),
'all' => pht('All Leases'),
);
}
public function buildSavedQueryFromBuiltin($query_key) {
$query = $this->newSavedQuery();
$query->setQueryKey($query_key);
switch ($query_key) {
case 'active':
return $query->setParameter(
'statuses',
array(
DrydockLeaseStatus::STATUS_PENDING,
DrydockLeaseStatus::STATUS_ACQUIRED,
DrydockLeaseStatus::STATUS_ACTIVE,
));
case 'all':
return $query;
}
return parent::buildSavedQueryFromBuiltin($query_key);
}
protected function renderResultList(
array $leases,
PhabricatorSavedQuery $saved,
array $handles) {
$list = id(new DrydockLeaseListView())
->setUser($this->requireViewer())
->setLeases($leases);
return id(new PhabricatorApplicationSearchResultView())
->setContent($list);
}
}

File Metadata

Mime Type
text/x-diff
Expires
Jan 19 2025, 21:25 (6 w, 1 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1128901
Default Alt Text
(17 KB)

Event Timeline