1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-03 11:21:01 +01:00

Make most Drydock web interfaces work with mobile

Summary: The logs bits still need some work but add crumbs/lists to everything else. Also build a propery DrydockResourceQuery.

Test Plan: Looked at lease list/detail; resource list/detail.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T2015

Differential Revision: https://secure.phabricator.com/D4221
This commit is contained in:
epriestley 2012-12-17 14:47:21 -08:00
parent ee392ada93
commit 53c1483ee5
10 changed files with 207 additions and 170 deletions

View file

@ -449,6 +449,7 @@ phutil_register_library_map(array(
'DrydockResource' => 'applications/drydock/storage/DrydockResource.php', 'DrydockResource' => 'applications/drydock/storage/DrydockResource.php',
'DrydockResourceCloseController' => 'applications/drydock/controller/DrydockResourceCloseController.php', 'DrydockResourceCloseController' => 'applications/drydock/controller/DrydockResourceCloseController.php',
'DrydockResourceListController' => 'applications/drydock/controller/DrydockResourceListController.php', 'DrydockResourceListController' => 'applications/drydock/controller/DrydockResourceListController.php',
'DrydockResourceQuery' => 'applications/drydock/query/DrydockResourceQuery.php',
'DrydockResourceStatus' => 'applications/drydock/constants/DrydockResourceStatus.php', 'DrydockResourceStatus' => 'applications/drydock/constants/DrydockResourceStatus.php',
'DrydockResourceViewController' => 'applications/drydock/controller/DrydockResourceViewController.php', 'DrydockResourceViewController' => 'applications/drydock/controller/DrydockResourceViewController.php',
'DrydockSSHCommandInterface' => 'applications/drydock/interface/command/DrydockSSHCommandInterface.php', 'DrydockSSHCommandInterface' => 'applications/drydock/interface/command/DrydockSSHCommandInterface.php',
@ -1739,6 +1740,7 @@ phutil_register_library_map(array(
'DrydockResource' => 'DrydockDAO', 'DrydockResource' => 'DrydockDAO',
'DrydockResourceCloseController' => 'DrydockController', 'DrydockResourceCloseController' => 'DrydockController',
'DrydockResourceListController' => 'DrydockController', 'DrydockResourceListController' => 'DrydockController',
'DrydockResourceQuery' => 'PhabricatorOffsetPagedQuery',
'DrydockResourceStatus' => 'DrydockConstants', 'DrydockResourceStatus' => 'DrydockConstants',
'DrydockResourceViewController' => 'DrydockController', 'DrydockResourceViewController' => 'DrydockController',
'DrydockSSHCommandInterface' => 'DrydockCommandInterface', 'DrydockSSHCommandInterface' => 'DrydockCommandInterface',

View file

@ -28,7 +28,7 @@ final class DrydockLocalHostBlueprint extends DrydockBlueprint {
Filesystem::assertIsDirectory($path); Filesystem::assertIsDirectory($path);
Filesystem::assertWritable($path); Filesystem::assertWritable($path);
$resource = $this->newResourceTemplate('localhost'); $resource = $this->newResourceTemplate('Host (localhost)');
$resource->setStatus(DrydockResourceStatus::STATUS_OPEN); $resource->setStatus(DrydockResourceStatus::STATUS_OPEN);
$resource->setAttribute('path', $path); $resource->setAttribute('path', $path);
$resource->save(); $resource->save();

View file

@ -62,7 +62,8 @@ final class DrydockWorkingCopyBlueprint extends DrydockBlueprint {
$this->log(pht('Complete.')); $this->log(pht('Complete.'));
$resource = $this->newResourceTemplate($repository->getCallsign()); $resource = $this->newResourceTemplate(
'Working Copy ('.$repository->getCallsign().')');
$resource->setStatus(DrydockResourceStatus::STATUS_OPEN); $resource->setStatus(DrydockResourceStatus::STATUS_OPEN);
$resource->setAttribute('lease.host', $host_lease->getID()); $resource->setAttribute('lease.host', $host_lease->getID());
$resource->setAttribute('path', $path); $resource->setAttribute('path', $path);

View file

@ -86,4 +86,88 @@ abstract class DrydockController extends PhabricatorController {
return $panel; return $panel;
} }
protected function buildLeaseListView(array $leases) {
assert_instances_of($leases, 'DrydockLease');
$user = $this->getRequest()->getUser();
$view = new PhabricatorObjectItemListView();
foreach ($leases as $lease) {
$item = id(new PhabricatorObjectItemView())
->setHeader($lease->getLeaseName())
->setHref($this->getApplicationURI('/lease/'.$lease->getID().'/'));
if ($lease->hasAttachedResource()) {
$resource = $lease->getResource();
$resource_href = '/resource/'.$resource->getID().'/';
$resource_href = $this->getApplicationURI($resource_href);
$resource_name = $resource->getName();
$item->addAttribute(
phutil_render_tag(
'a',
array(
'href' => $resource_href,
),
phutil_escape_html($resource_name)));
}
$status = DrydockLeaseStatus::getNameForStatus($lease->getStatus());
$item->addAttribute(phutil_escape_html($status));
$date_created = phabricator_date($lease->getDateCreated(), $user);
$item->addAttribute(pht('Created on %s', $date_created));
if ($lease->isActive()) {
$item->setBarColor('green');
} else {
$item->setBarColor('red');
}
$view->addItem($item);
}
return $view;
}
protected function buildResourceListView(array $resources) {
assert_instances_of($resources, 'DrydockResource');
$user = $this->getRequest()->getUser();
$view = new PhabricatorObjectItemListView();
foreach ($resources as $resource) {
$name = pht('Resource %d', $resource->getID()).': '.$resource->getName();
$item = id(new PhabricatorObjectItemView())
->setHref($this->getApplicationURI('/resource/'.$resource->getID().'/'))
->setHeader($name);
$status = DrydockResourceStatus::getNameForStatus($resource->getStatus());
$item->addAttribute($status);
switch ($resource->getStatus()) {
case DrydockResourceStatus::STATUS_PENDING:
$item->setBarColor('yellow');
break;
case DrydockResourceStatus::STATUS_OPEN:
$item->setBarColor('green');
break;
case DrydockResourceStatus::STATUS_DESTROYED:
$item->setBarColor('black');
break;
default:
$item->setBarColor('red');
break;
}
$view->addItem($item);
}
return $view;
}
} }

View file

@ -12,84 +12,36 @@ final class DrydockLeaseListController extends DrydockController {
$pager->setURI(new PhutilURI('/drydock/lease/'), 'offset'); $pager->setURI(new PhutilURI('/drydock/lease/'), 'offset');
$pager->setOffset($request->getInt('offset')); $pager->setOffset($request->getInt('offset'));
$data = id(new DrydockLease())->loadAllWhere( $leases = id(new DrydockLeaseQuery())
'1 = 1 ORDER BY id DESC LIMIT %d, %d', ->needResources(true)
$pager->getOffset(), ->executeWithOffsetPager($pager);
$pager->getPageSize() + 1);
$data = $pager->sliceResults($data);
$resource_ids = mpull($data, 'getResourceID'); $title = pht('Leases');
$resources = array();
if ($resource_ids) {
$resources = id(new DrydockResource())->loadAllWhere(
'id IN (%Ld)',
$resource_ids);
}
$rows = array(); $header = id(new PhabricatorHeaderView())
foreach ($data as $lease) { ->setHeader($title);
$resource = idx($resources, $lease->getResourceID());
$lease_uri = '/lease/'.$lease->getID().'/'; $lease_list = $this->buildLeaseListView($leases);
$lease_uri = $this->getApplicationURI($lease_uri);
$resource_uri = '/resource/'.$lease->getResourceID().'/'; $nav->appendChild(
$resource_uri = $this->getApplicationURI($resource_uri);
$rows[] = array(
phutil_render_tag(
'a',
array(
'href' => $lease_uri,
),
$lease->getID()),
phutil_render_tag(
'a',
array(
'href' => $resource_uri,
),
$lease->getResourceID()),
DrydockLeaseStatus::getNameForStatus($lease->getStatus()),
phutil_escape_html($lease->getResourceType()),
($resource
? phutil_escape_html($resource->getName())
: null),
phabricator_datetime($lease->getDateCreated(), $user),
);
}
$table = new AphrontTableView($rows);
$table->setHeaders(
array( array(
'ID', $header,
'Resource ID', $lease_list,
'Status', $pager,
'Resource Type',
'Resource',
'Created',
));
$table->setColumnClasses(
array(
'',
'',
'',
'',
'wide pri',
'right',
)); ));
$panel = new AphrontPanelView(); $crumbs = $this->buildApplicationCrumbs();
$panel->setHeader('Drydock Leases'); $crumbs->addCrumb(
id(new PhabricatorCrumbView())
->setName($title)
->setHref($request->getRequestURI()));
$nav->setCrumbs($crumbs);
$panel->appendChild($table); return $this->buildApplicationPage(
$panel->appendChild($pager);
$nav->appendChild($panel);
return $this->buildStandardPageResponse(
$nav, $nav,
array( array(
'device' => true, 'device' => true,
'title' => 'Leases', 'title' => $title,
)); ));
} }

View file

@ -12,14 +12,14 @@ final class DrydockLeaseViewController extends DrydockController {
$request = $this->getRequest(); $request = $this->getRequest();
$user = $request->getUser(); $user = $request->getUser();
$nav = $this->buildSideNav('lease');
$lease = id(new DrydockLease())->load($this->id); $lease = id(new DrydockLease())->load($this->id);
if (!$lease) { if (!$lease) {
return new Aphront404Response(); return new Aphront404Response();
} }
$title = 'Lease '.$lease->getID(); $lease_uri = $this->getApplicationURI('lease/'.$lease->getID().'/');
$title = pht('Lease %d', $lease->getID());
$header = id(new PhabricatorHeaderView()) $header = id(new PhabricatorHeaderView())
->setHeader($title); ->setHeader($title);
@ -28,9 +28,7 @@ final class DrydockLeaseViewController extends DrydockController {
$properties = $this->buildPropertyListView($lease); $properties = $this->buildPropertyListView($lease);
$pager = new AphrontPagerView(); $pager = new AphrontPagerView();
$pager->setURI( $pager->setURI(new PhutilURI($lease_uri), 'offset');
new PhutilURI($this->getApplicationURI('lease/'.$lease->getID().'/')),
'offset');
$pager->setOffset($request->getInt('offset')); $pager->setOffset($request->getInt('offset'));
$logs = id(new DrydockLogQuery()) $logs = id(new DrydockLogQuery())
@ -40,16 +38,20 @@ final class DrydockLeaseViewController extends DrydockController {
$log_table = $this->buildLogTableView($logs); $log_table = $this->buildLogTableView($logs);
$log_table->appendChild($pager); $log_table->appendChild($pager);
$nav->appendChild( $crumbs = $this->buildApplicationCrumbs();
$crumbs->addCrumb(
id(new PhabricatorCrumbView())
->setName($title)
->setHref($lease_uri));
return $this->buildApplicationPage(
array( array(
$crumbs,
$header, $header,
$actions, $actions,
$properties, $properties,
$log_table, $log_table,
)); ),
return $this->buildApplicationPage(
$nav,
array( array(
'device' => true, 'device' => true,
'title' => $title, 'title' => $title,

View file

@ -6,66 +6,38 @@ final class DrydockResourceListController extends DrydockController {
$request = $this->getRequest(); $request = $this->getRequest();
$user = $request->getUser(); $user = $request->getUser();
$nav = $this->buildSideNav('resource'); $title = pht('Resources');
$resource_header = id(new PhabricatorHeaderView())
->setHeader($title);
$pager = new AphrontPagerView(); $pager = new AphrontPagerView();
$pager->setURI(new PhutilURI('/drydock/resource/'), 'page'); $pager->setURI(new PhutilURI('/drydock/resource/'), 'offset');
$resources = id(new DrydockResourceQuery())
->executeWithOffsetPager($pager);
$data = id(new DrydockResource())->loadAllWhere( $resource_list = $this->buildResourceListView($resources);
'1 = 1 ORDER BY id DESC LIMIT %d, %d',
$pager->getOffset(),
$pager->getPageSize() + 1);
$data = $pager->sliceResults($data);
$rows = array(); $crumbs = $this->buildApplicationCrumbs();
foreach ($data as $resource) { $crumbs->addCrumb(
$resource_uri = '/resource/'.$resource->getID().'/'; id(new PhabricatorCrumbView())
$resource_uri = $this->getApplicationURI($resource_uri); ->setName($title)
->setHref($request->getRequestURI()));
$rows[] = array( $nav = $this->buildSideNav('resource');
phutil_render_tag( $nav->setCrumbs($crumbs);
'a', $nav->appendChild(
array(
'href' => $resource_uri,
),
$resource->getID()),
phutil_escape_html($resource->getType()),
DrydockResourceStatus::getNameForStatus($resource->getStatus()),
phutil_escape_html(nonempty($resource->getName(), 'Unnamed')),
phabricator_datetime($resource->getDateCreated(), $user),
);
}
$table = new AphrontTableView($rows);
$table->setHeaders(
array( array(
'ID', $resource_header,
'Type', $resource_list,
'Status', $pager,
'Resource',
'Created',
));
$table->setColumnClasses(
array(
'',
'',
'',
'pri wide',
'right',
)); ));
$panel = new AphrontPanelView(); return $this->buildApplicationPage(
$panel->setHeader('Drydock Resources');
$panel->appendChild($table);
$panel->appendChild($pager);
$nav->appendChild($panel);
return $this->buildStandardPageResponse(
$nav, $nav,
array( array(
'title' => 'Resources', 'title' => $title,
'device' => true,
)); ));
} }

View file

@ -12,8 +12,6 @@ final class DrydockResourceViewController extends DrydockController {
$request = $this->getRequest(); $request = $this->getRequest();
$user = $request->getUser(); $user = $request->getUser();
$nav = $this->buildSideNav('resource');
$resource = id(new DrydockResource())->load($this->id); $resource = id(new DrydockResource())->load($this->id);
if (!$resource) { if (!$resource) {
return new Aphront404Response(); return new Aphront404Response();
@ -32,8 +30,12 @@ final class DrydockResourceViewController extends DrydockController {
$leases = id(new DrydockLeaseQuery()) $leases = id(new DrydockLeaseQuery())
->withResourceIDs(array($resource->getID())) ->withResourceIDs(array($resource->getID()))
->needResources(true)
->execute(); ->execute();
$lease_header = id(new PhabricatorHeaderView())
->setHeader(pht('Leases'));
$lease_list = $this->buildLeaseListView($leases); $lease_list = $this->buildLeaseListView($leases);
$lease_list->setNoDataString(pht('This resource has no leases.')); $lease_list->setNoDataString(pht('This resource has no leases.'));
@ -48,17 +50,21 @@ final class DrydockResourceViewController extends DrydockController {
$log_table = $this->buildLogTableView($logs); $log_table = $this->buildLogTableView($logs);
$log_table->appendChild($pager); $log_table->appendChild($pager);
$nav->appendChild( $crumbs = $this->buildApplicationCrumbs();
$crumbs->addCrumb(
id(new PhabricatorCrumbView())
->setName(pht('Resource %d', $resource->getID())));
return $this->buildApplicationPage(
array( array(
$crumbs,
$header, $header,
$actions, $actions,
$properties, $properties,
$lease_header,
$lease_list, $lease_list,
$log_table, $log_table,
)); ),
return $this->buildApplicationPage(
$nav,
array( array(
'device' => true, 'device' => true,
'title' => $title, 'title' => $title,
@ -114,34 +120,4 @@ final class DrydockResourceViewController extends DrydockController {
return $view; return $view;
} }
private function buildLeaseListView(array $leases) {
assert_instances_of($leases, 'DrydockLease');
$user = $this->getRequest()->getUser();
$view = new PhabricatorObjectItemListView();
foreach ($leases as $lease) {
$item = id(new PhabricatorObjectItemView())
->setHeader($lease->getLeaseName())
->setHref($this->getApplicationURI('/lease/'.$lease->getID().'/'));
$status = DrydockLeaseStatus::getNameForStatus($lease->getStatus());
$item->addAttribute(phutil_escape_html($status));
$date_created = phabricator_date($lease->getDateCreated(), $user);
$item->addAttribute(pht('Created on %s', $date_created));
if ($lease->isActive()) {
$item->setBarColor('green');
} else {
$item->setBarColor('red');
}
$view->addItem($item);
}
return $view;
}
} }

View file

@ -0,0 +1,46 @@
<?php
final class DrydockResourceQuery extends PhabricatorOffsetPagedQuery {
private $ids;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function execute() {
$table = new DrydockResource();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT resource.* FROM %T resource %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$resources = $table->loadAllFromArray($data);
return $resources;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
return $this->formatWhereClause($where);
}
private function buildOrderClause(AphrontDatabaseConnection $conn_r) {
return qsprintf($conn_r, 'ORDER BY id DESC');
}
}

View file

@ -64,7 +64,6 @@ final class DrydockLease extends DrydockDAO {
} }
public function getResource() { public function getResource() {
$this->assertActive();
if ($this->resource === null) { if ($this->resource === null) {
throw new Exception("Resource is not yet loaded."); throw new Exception("Resource is not yet loaded.");
} }
@ -72,13 +71,15 @@ final class DrydockLease extends DrydockDAO {
} }
public function attachResource(DrydockResource $resource) { public function attachResource(DrydockResource $resource) {
$this->assertActive();
$this->resource = $resource; $this->resource = $resource;
return $this; return $this;
} }
public function hasAttachedResource() {
return ($this->resource !== null);
}
public function loadResource() { public function loadResource() {
$this->assertActive();
return id(new DrydockResource())->loadOneWhere( return id(new DrydockResource())->loadOneWhere(
'id = %d', 'id = %d',
$this->getResourceID()); $this->getResourceID());
@ -115,6 +116,7 @@ final class DrydockLease extends DrydockDAO {
} }
public function release() { public function release() {
$this->assertActive();
$this->setStatus(DrydockLeaseStatus::STATUS_RELEASED); $this->setStatus(DrydockLeaseStatus::STATUS_RELEASED);
$this->save(); $this->save();