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 @@ -64,6 +64,8 @@ '(?P[1-9]\d*)/' => array( '' => 'DrydockResourceViewController', 'release/' => 'DrydockResourceReleaseController', + 'leases/(?:query/(?P[^/]+)/)?' => + 'DrydockLeaseListController', ), ), 'lease/' => array( diff --git a/src/applications/drydock/controller/DrydockLeaseController.php b/src/applications/drydock/controller/DrydockLeaseController.php --- a/src/applications/drydock/controller/DrydockLeaseController.php +++ b/src/applications/drydock/controller/DrydockLeaseController.php @@ -3,13 +3,29 @@ 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); @@ -18,9 +34,28 @@ 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 --- a/src/applications/drydock/controller/DrydockLeaseListController.php +++ b/src/applications/drydock/controller/DrydockLeaseListController.php @@ -8,11 +8,26 @@ 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 --- a/src/applications/drydock/controller/DrydockResourceController.php +++ b/src/applications/drydock/controller/DrydockResourceController.php @@ -18,9 +18,14 @@ $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); diff --git a/src/applications/drydock/controller/DrydockResourceViewController.php b/src/applications/drydock/controller/DrydockResourceViewController.php --- a/src/applications/drydock/controller/DrydockResourceViewController.php +++ b/src/applications/drydock/controller/DrydockResourceViewController.php @@ -27,17 +27,6 @@ $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')); @@ -65,9 +54,7 @@ ->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')) @@ -149,4 +136,43 @@ 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 --- a/src/applications/drydock/query/DrydockLeaseSearchEngine.php +++ b/src/applications/drydock/query/DrydockLeaseSearchEngine.php @@ -3,6 +3,17 @@ 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'); } @@ -12,7 +23,14 @@ } 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) { @@ -35,7 +53,13 @@ } 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() {