@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+207 -170
+2
src/__phutil_library_map__.php
··· 449 449 'DrydockResource' => 'applications/drydock/storage/DrydockResource.php', 450 450 'DrydockResourceCloseController' => 'applications/drydock/controller/DrydockResourceCloseController.php', 451 451 'DrydockResourceListController' => 'applications/drydock/controller/DrydockResourceListController.php', 452 + 'DrydockResourceQuery' => 'applications/drydock/query/DrydockResourceQuery.php', 452 453 'DrydockResourceStatus' => 'applications/drydock/constants/DrydockResourceStatus.php', 453 454 'DrydockResourceViewController' => 'applications/drydock/controller/DrydockResourceViewController.php', 454 455 'DrydockSSHCommandInterface' => 'applications/drydock/interface/command/DrydockSSHCommandInterface.php', ··· 1739 1740 'DrydockResource' => 'DrydockDAO', 1740 1741 'DrydockResourceCloseController' => 'DrydockController', 1741 1742 'DrydockResourceListController' => 'DrydockController', 1743 + 'DrydockResourceQuery' => 'PhabricatorOffsetPagedQuery', 1742 1744 'DrydockResourceStatus' => 'DrydockConstants', 1743 1745 'DrydockResourceViewController' => 'DrydockController', 1744 1746 'DrydockSSHCommandInterface' => 'DrydockCommandInterface',
+1 -1
src/applications/drydock/blueprint/DrydockLocalHostBlueprint.php
··· 28 28 Filesystem::assertIsDirectory($path); 29 29 Filesystem::assertWritable($path); 30 30 31 - $resource = $this->newResourceTemplate('localhost'); 31 + $resource = $this->newResourceTemplate('Host (localhost)'); 32 32 $resource->setStatus(DrydockResourceStatus::STATUS_OPEN); 33 33 $resource->setAttribute('path', $path); 34 34 $resource->save();
+2 -1
src/applications/drydock/blueprint/DrydockWorkingCopyBlueprint.php
··· 62 62 63 63 $this->log(pht('Complete.')); 64 64 65 - $resource = $this->newResourceTemplate($repository->getCallsign()); 65 + $resource = $this->newResourceTemplate( 66 + 'Working Copy ('.$repository->getCallsign().')'); 66 67 $resource->setStatus(DrydockResourceStatus::STATUS_OPEN); 67 68 $resource->setAttribute('lease.host', $host_lease->getID()); 68 69 $resource->setAttribute('path', $path);
+84
src/applications/drydock/controller/DrydockController.php
··· 86 86 return $panel; 87 87 } 88 88 89 + protected function buildLeaseListView(array $leases) { 90 + assert_instances_of($leases, 'DrydockLease'); 91 + 92 + $user = $this->getRequest()->getUser(); 93 + $view = new PhabricatorObjectItemListView(); 94 + 95 + foreach ($leases as $lease) { 96 + $item = id(new PhabricatorObjectItemView()) 97 + ->setHeader($lease->getLeaseName()) 98 + ->setHref($this->getApplicationURI('/lease/'.$lease->getID().'/')); 99 + 100 + if ($lease->hasAttachedResource()) { 101 + $resource = $lease->getResource(); 102 + 103 + $resource_href = '/resource/'.$resource->getID().'/'; 104 + $resource_href = $this->getApplicationURI($resource_href); 105 + 106 + $resource_name = $resource->getName(); 107 + 108 + $item->addAttribute( 109 + phutil_render_tag( 110 + 'a', 111 + array( 112 + 'href' => $resource_href, 113 + ), 114 + phutil_escape_html($resource_name))); 115 + } 116 + 117 + $status = DrydockLeaseStatus::getNameForStatus($lease->getStatus()); 118 + $item->addAttribute(phutil_escape_html($status)); 119 + 120 + $date_created = phabricator_date($lease->getDateCreated(), $user); 121 + $item->addAttribute(pht('Created on %s', $date_created)); 122 + 123 + if ($lease->isActive()) { 124 + $item->setBarColor('green'); 125 + } else { 126 + $item->setBarColor('red'); 127 + } 128 + 129 + $view->addItem($item); 130 + } 131 + 132 + return $view; 133 + } 134 + 135 + protected function buildResourceListView(array $resources) { 136 + assert_instances_of($resources, 'DrydockResource'); 137 + 138 + $user = $this->getRequest()->getUser(); 139 + $view = new PhabricatorObjectItemListView(); 140 + 141 + foreach ($resources as $resource) { 142 + $name = pht('Resource %d', $resource->getID()).': '.$resource->getName(); 143 + 144 + $item = id(new PhabricatorObjectItemView()) 145 + ->setHref($this->getApplicationURI('/resource/'.$resource->getID().'/')) 146 + ->setHeader($name); 147 + 148 + $status = DrydockResourceStatus::getNameForStatus($resource->getStatus()); 149 + $item->addAttribute($status); 150 + 151 + switch ($resource->getStatus()) { 152 + case DrydockResourceStatus::STATUS_PENDING: 153 + $item->setBarColor('yellow'); 154 + break; 155 + case DrydockResourceStatus::STATUS_OPEN: 156 + $item->setBarColor('green'); 157 + break; 158 + case DrydockResourceStatus::STATUS_DESTROYED: 159 + $item->setBarColor('black'); 160 + break; 161 + default: 162 + $item->setBarColor('red'); 163 + break; 164 + } 165 + 166 + $view->addItem($item); 167 + } 168 + 169 + return $view; 170 + } 171 + 172 + 89 173 }
+19 -67
src/applications/drydock/controller/DrydockLeaseListController.php
··· 12 12 $pager->setURI(new PhutilURI('/drydock/lease/'), 'offset'); 13 13 $pager->setOffset($request->getInt('offset')); 14 14 15 - $data = id(new DrydockLease())->loadAllWhere( 16 - '1 = 1 ORDER BY id DESC LIMIT %d, %d', 17 - $pager->getOffset(), 18 - $pager->getPageSize() + 1); 19 - $data = $pager->sliceResults($data); 15 + $leases = id(new DrydockLeaseQuery()) 16 + ->needResources(true) 17 + ->executeWithOffsetPager($pager); 20 18 21 - $resource_ids = mpull($data, 'getResourceID'); 22 - $resources = array(); 23 - if ($resource_ids) { 24 - $resources = id(new DrydockResource())->loadAllWhere( 25 - 'id IN (%Ld)', 26 - $resource_ids); 27 - } 19 + $title = pht('Leases'); 28 20 29 - $rows = array(); 30 - foreach ($data as $lease) { 31 - $resource = idx($resources, $lease->getResourceID()); 21 + $header = id(new PhabricatorHeaderView()) 22 + ->setHeader($title); 32 23 33 - $lease_uri = '/lease/'.$lease->getID().'/'; 34 - $lease_uri = $this->getApplicationURI($lease_uri); 35 - 36 - $resource_uri = '/resource/'.$lease->getResourceID().'/'; 37 - $resource_uri = $this->getApplicationURI($resource_uri); 38 - 39 - $rows[] = array( 40 - phutil_render_tag( 41 - 'a', 42 - array( 43 - 'href' => $lease_uri, 44 - ), 45 - $lease->getID()), 46 - phutil_render_tag( 47 - 'a', 48 - array( 49 - 'href' => $resource_uri, 50 - ), 51 - $lease->getResourceID()), 52 - DrydockLeaseStatus::getNameForStatus($lease->getStatus()), 53 - phutil_escape_html($lease->getResourceType()), 54 - ($resource 55 - ? phutil_escape_html($resource->getName()) 56 - : null), 57 - phabricator_datetime($lease->getDateCreated(), $user), 58 - ); 59 - } 24 + $lease_list = $this->buildLeaseListView($leases); 60 25 61 - $table = new AphrontTableView($rows); 62 - $table->setHeaders( 26 + $nav->appendChild( 63 27 array( 64 - 'ID', 65 - 'Resource ID', 66 - 'Status', 67 - 'Resource Type', 68 - 'Resource', 69 - 'Created', 70 - )); 71 - $table->setColumnClasses( 72 - array( 73 - '', 74 - '', 75 - '', 76 - '', 77 - 'wide pri', 78 - 'right', 28 + $header, 29 + $lease_list, 30 + $pager, 79 31 )); 80 32 81 - $panel = new AphrontPanelView(); 82 - $panel->setHeader('Drydock Leases'); 83 - 84 - $panel->appendChild($table); 85 - $panel->appendChild($pager); 33 + $crumbs = $this->buildApplicationCrumbs(); 34 + $crumbs->addCrumb( 35 + id(new PhabricatorCrumbView()) 36 + ->setName($title) 37 + ->setHref($request->getRequestURI())); 38 + $nav->setCrumbs($crumbs); 86 39 87 - $nav->appendChild($panel); 88 - return $this->buildStandardPageResponse( 40 + return $this->buildApplicationPage( 89 41 $nav, 90 42 array( 91 43 'device' => true, 92 - 'title' => 'Leases', 44 + 'title' => $title, 93 45 )); 94 46 95 47 }
+13 -11
src/applications/drydock/controller/DrydockLeaseViewController.php
··· 12 12 $request = $this->getRequest(); 13 13 $user = $request->getUser(); 14 14 15 - $nav = $this->buildSideNav('lease'); 16 - 17 15 $lease = id(new DrydockLease())->load($this->id); 18 16 if (!$lease) { 19 17 return new Aphront404Response(); 20 18 } 21 19 22 - $title = 'Lease '.$lease->getID(); 20 + $lease_uri = $this->getApplicationURI('lease/'.$lease->getID().'/'); 21 + 22 + $title = pht('Lease %d', $lease->getID()); 23 23 24 24 $header = id(new PhabricatorHeaderView()) 25 25 ->setHeader($title); ··· 28 28 $properties = $this->buildPropertyListView($lease); 29 29 30 30 $pager = new AphrontPagerView(); 31 - $pager->setURI( 32 - new PhutilURI($this->getApplicationURI('lease/'.$lease->getID().'/')), 33 - 'offset'); 31 + $pager->setURI(new PhutilURI($lease_uri), 'offset'); 34 32 $pager->setOffset($request->getInt('offset')); 35 33 36 34 $logs = id(new DrydockLogQuery()) ··· 40 38 $log_table = $this->buildLogTableView($logs); 41 39 $log_table->appendChild($pager); 42 40 43 - $nav->appendChild( 41 + $crumbs = $this->buildApplicationCrumbs(); 42 + $crumbs->addCrumb( 43 + id(new PhabricatorCrumbView()) 44 + ->setName($title) 45 + ->setHref($lease_uri)); 46 + 47 + return $this->buildApplicationPage( 44 48 array( 49 + $crumbs, 45 50 $header, 46 51 $actions, 47 52 $properties, 48 53 $log_table, 49 - )); 50 - 51 - return $this->buildApplicationPage( 52 - $nav, 54 + ), 53 55 array( 54 56 'device' => true, 55 57 'title' => $title,
+22 -50
src/applications/drydock/controller/DrydockResourceListController.php
··· 6 6 $request = $this->getRequest(); 7 7 $user = $request->getUser(); 8 8 9 - $nav = $this->buildSideNav('resource'); 9 + $title = pht('Resources'); 10 10 11 - $pager = new AphrontPagerView(); 12 - $pager->setURI(new PhutilURI('/drydock/resource/'), 'page'); 11 + $resource_header = id(new PhabricatorHeaderView()) 12 + ->setHeader($title); 13 13 14 - $data = id(new DrydockResource())->loadAllWhere( 15 - '1 = 1 ORDER BY id DESC LIMIT %d, %d', 16 - $pager->getOffset(), 17 - $pager->getPageSize() + 1); 18 - $data = $pager->sliceResults($data); 14 + $pager = new AphrontPagerView(); 15 + $pager->setURI(new PhutilURI('/drydock/resource/'), 'offset'); 16 + $resources = id(new DrydockResourceQuery()) 17 + ->executeWithOffsetPager($pager); 19 18 20 - $rows = array(); 21 - foreach ($data as $resource) { 22 - $resource_uri = '/resource/'.$resource->getID().'/'; 23 - $resource_uri = $this->getApplicationURI($resource_uri); 19 + $resource_list = $this->buildResourceListView($resources); 24 20 25 - $rows[] = array( 26 - phutil_render_tag( 27 - 'a', 28 - array( 29 - 'href' => $resource_uri, 30 - ), 31 - $resource->getID()), 32 - phutil_escape_html($resource->getType()), 33 - DrydockResourceStatus::getNameForStatus($resource->getStatus()), 34 - phutil_escape_html(nonempty($resource->getName(), 'Unnamed')), 35 - phabricator_datetime($resource->getDateCreated(), $user), 36 - ); 37 - } 21 + $crumbs = $this->buildApplicationCrumbs(); 22 + $crumbs->addCrumb( 23 + id(new PhabricatorCrumbView()) 24 + ->setName($title) 25 + ->setHref($request->getRequestURI())); 38 26 39 - $table = new AphrontTableView($rows); 40 - $table->setHeaders( 41 - array( 42 - 'ID', 43 - 'Type', 44 - 'Status', 45 - 'Resource', 46 - 'Created', 47 - )); 48 - $table->setColumnClasses( 27 + $nav = $this->buildSideNav('resource'); 28 + $nav->setCrumbs($crumbs); 29 + $nav->appendChild( 49 30 array( 50 - '', 51 - '', 52 - '', 53 - 'pri wide', 54 - 'right', 31 + $resource_header, 32 + $resource_list, 33 + $pager, 55 34 )); 56 35 57 - $panel = new AphrontPanelView(); 58 - $panel->setHeader('Drydock Resources'); 59 - 60 - $panel->appendChild($table); 61 - $panel->appendChild($pager); 62 - 63 - $nav->appendChild($panel); 64 - 65 - return $this->buildStandardPageResponse( 36 + return $this->buildApplicationPage( 66 37 $nav, 67 38 array( 68 - 'title' => 'Resources', 39 + 'title' => $title, 40 + 'device' => true, 69 41 )); 70 42 71 43 }
+13 -37
src/applications/drydock/controller/DrydockResourceViewController.php
··· 12 12 $request = $this->getRequest(); 13 13 $user = $request->getUser(); 14 14 15 - $nav = $this->buildSideNav('resource'); 16 - 17 15 $resource = id(new DrydockResource())->load($this->id); 18 16 if (!$resource) { 19 17 return new Aphront404Response(); ··· 32 30 33 31 $leases = id(new DrydockLeaseQuery()) 34 32 ->withResourceIDs(array($resource->getID())) 33 + ->needResources(true) 35 34 ->execute(); 36 35 36 + $lease_header = id(new PhabricatorHeaderView()) 37 + ->setHeader(pht('Leases')); 38 + 37 39 $lease_list = $this->buildLeaseListView($leases); 38 40 $lease_list->setNoDataString(pht('This resource has no leases.')); 39 41 ··· 48 50 $log_table = $this->buildLogTableView($logs); 49 51 $log_table->appendChild($pager); 50 52 51 - $nav->appendChild( 53 + $crumbs = $this->buildApplicationCrumbs(); 54 + $crumbs->addCrumb( 55 + id(new PhabricatorCrumbView()) 56 + ->setName(pht('Resource %d', $resource->getID()))); 57 + 58 + return $this->buildApplicationPage( 52 59 array( 60 + $crumbs, 53 61 $header, 54 62 $actions, 55 63 $properties, 64 + $lease_header, 56 65 $lease_list, 57 66 $log_table, 58 - )); 59 - 60 - return $this->buildApplicationPage( 61 - $nav, 67 + ), 62 68 array( 63 69 'device' => true, 64 70 'title' => $title, ··· 109 115 phutil_escape_html($key), 110 116 phutil_escape_html($value)); 111 117 } 112 - } 113 - 114 - return $view; 115 - } 116 - 117 - private function buildLeaseListView(array $leases) { 118 - assert_instances_of($leases, 'DrydockLease'); 119 - 120 - $user = $this->getRequest()->getUser(); 121 - 122 - $view = new PhabricatorObjectItemListView(); 123 - 124 - foreach ($leases as $lease) { 125 - $item = id(new PhabricatorObjectItemView()) 126 - ->setHeader($lease->getLeaseName()) 127 - ->setHref($this->getApplicationURI('/lease/'.$lease->getID().'/')); 128 - 129 - $status = DrydockLeaseStatus::getNameForStatus($lease->getStatus()); 130 - $item->addAttribute(phutil_escape_html($status)); 131 - 132 - $date_created = phabricator_date($lease->getDateCreated(), $user); 133 - $item->addAttribute(pht('Created on %s', $date_created)); 134 - 135 - if ($lease->isActive()) { 136 - $item->setBarColor('green'); 137 - } else { 138 - $item->setBarColor('red'); 139 - } 140 - 141 - $view->addItem($item); 142 118 } 143 119 144 120 return $view;
+46
src/applications/drydock/query/DrydockResourceQuery.php
··· 1 + <?php 2 + 3 + final class DrydockResourceQuery extends PhabricatorOffsetPagedQuery { 4 + 5 + private $ids; 6 + 7 + public function withIDs(array $ids) { 8 + $this->ids = $ids; 9 + return $this; 10 + } 11 + 12 + public function execute() { 13 + $table = new DrydockResource(); 14 + $conn_r = $table->establishConnection('r'); 15 + 16 + $data = queryfx_all( 17 + $conn_r, 18 + 'SELECT resource.* FROM %T resource %Q %Q %Q', 19 + $table->getTableName(), 20 + $this->buildWhereClause($conn_r), 21 + $this->buildOrderClause($conn_r), 22 + $this->buildLimitClause($conn_r)); 23 + 24 + $resources = $table->loadAllFromArray($data); 25 + 26 + return $resources; 27 + } 28 + 29 + private function buildWhereClause(AphrontDatabaseConnection $conn_r) { 30 + $where = array(); 31 + 32 + if ($this->ids) { 33 + $where[] = qsprintf( 34 + $conn_r, 35 + 'id IN (%Ld)', 36 + $this->ids); 37 + } 38 + 39 + return $this->formatWhereClause($where); 40 + } 41 + 42 + private function buildOrderClause(AphrontDatabaseConnection $conn_r) { 43 + return qsprintf($conn_r, 'ORDER BY id DESC'); 44 + } 45 + 46 + }
+5 -3
src/applications/drydock/storage/DrydockLease.php
··· 64 64 } 65 65 66 66 public function getResource() { 67 - $this->assertActive(); 68 67 if ($this->resource === null) { 69 68 throw new Exception("Resource is not yet loaded."); 70 69 } ··· 72 71 } 73 72 74 73 public function attachResource(DrydockResource $resource) { 75 - $this->assertActive(); 76 74 $this->resource = $resource; 77 75 return $this; 78 76 } 79 77 78 + public function hasAttachedResource() { 79 + return ($this->resource !== null); 80 + } 81 + 80 82 public function loadResource() { 81 - $this->assertActive(); 82 83 return id(new DrydockResource())->loadOneWhere( 83 84 'id = %d', 84 85 $this->getResourceID()); ··· 115 116 } 116 117 117 118 public function release() { 119 + $this->assertActive(); 118 120 $this->setStatus(DrydockLeaseStatus::STATUS_RELEASED); 119 121 $this->save(); 120 122