@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 all of Drydock work on Mobile

Summary: This is probably not the most useful app to have work on mobile, but get the log view to do something fairly sensible.

Test Plan: Looked at all Drydock views in mobile.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T2015

Differential Revision: https://secure.phabricator.com/D4224

+213 -92
+64 -64
src/__celerity_resource_map__.php
··· 690 690 ), 691 691 'aphront-table-view-css' => 692 692 array( 693 - 'uri' => '/res/d2cd4818/rsrc/css/aphront/table-view.css', 693 + 'uri' => '/res/94d76d56/rsrc/css/aphront/table-view.css', 694 694 'type' => 'css', 695 695 'requires' => 696 696 array( ··· 1094 1094 ), 1095 1095 'javelin-behavior-differential-accept-with-errors' => 1096 1096 array( 1097 - 'uri' => '/res/ba5144c5/rsrc/js/application/differential/behavior-accept-with-errors.js', 1097 + 'uri' => '/res/8fea67b3/rsrc/js/application/differential/behavior-accept-with-errors.js', 1098 1098 'type' => 'js', 1099 1099 'requires' => 1100 1100 array( ··· 3201 3201 ), array( 3202 3202 'packages' => 3203 3203 array( 3204 - '736c46dd' => 3204 + '6d338e1d' => 3205 3205 array( 3206 3206 'name' => 'core.pkg.css', 3207 3207 'symbols' => ··· 3246 3246 37 => 'phabricator-object-item-list-view-css', 3247 3247 38 => 'global-drag-and-drop-css', 3248 3248 ), 3249 - 'uri' => '/res/pkg/736c46dd/core.pkg.css', 3249 + 'uri' => '/res/pkg/6d338e1d/core.pkg.css', 3250 3250 'type' => 'css', 3251 3251 ), 3252 3252 '70c8162b' => ··· 3325 3325 'uri' => '/res/pkg/380df740/differential.pkg.css', 3326 3326 'type' => 'css', 3327 3327 ), 3328 - 'a8e8f2b7' => 3328 + '8b98837e' => 3329 3329 array( 3330 3330 'name' => 'differential.pkg.js', 3331 3331 'symbols' => ··· 3350 3350 17 => 'javelin-behavior-differential-toggle-files', 3351 3351 18 => 'javelin-behavior-differential-user-select', 3352 3352 ), 3353 - 'uri' => '/res/pkg/a8e8f2b7/differential.pkg.js', 3353 + 'uri' => '/res/pkg/8b98837e/differential.pkg.js', 3354 3354 'type' => 'js', 3355 3355 ), 3356 3356 'c8ce2d88' => ··· 3435 3435 'reverse' => 3436 3436 array( 3437 3437 'aphront-attached-file-view-css' => '7839ae2d', 3438 - 'aphront-crumbs-view-css' => '736c46dd', 3439 - 'aphront-dialog-view-css' => '736c46dd', 3440 - 'aphront-error-view-css' => '736c46dd', 3441 - 'aphront-form-view-css' => '736c46dd', 3438 + 'aphront-crumbs-view-css' => '6d338e1d', 3439 + 'aphront-dialog-view-css' => '6d338e1d', 3440 + 'aphront-error-view-css' => '6d338e1d', 3441 + 'aphront-form-view-css' => '6d338e1d', 3442 3442 'aphront-headsup-action-list-view-css' => '380df740', 3443 - 'aphront-headsup-view-css' => '736c46dd', 3444 - 'aphront-list-filter-view-css' => '736c46dd', 3445 - 'aphront-pager-view-css' => '736c46dd', 3446 - 'aphront-panel-view-css' => '736c46dd', 3447 - 'aphront-side-nav-view-css' => '736c46dd', 3448 - 'aphront-table-view-css' => '736c46dd', 3449 - 'aphront-tokenizer-control-css' => '736c46dd', 3450 - 'aphront-tooltip-css' => '736c46dd', 3451 - 'aphront-typeahead-control-css' => '736c46dd', 3443 + 'aphront-headsup-view-css' => '6d338e1d', 3444 + 'aphront-list-filter-view-css' => '6d338e1d', 3445 + 'aphront-pager-view-css' => '6d338e1d', 3446 + 'aphront-panel-view-css' => '6d338e1d', 3447 + 'aphront-side-nav-view-css' => '6d338e1d', 3448 + 'aphront-table-view-css' => '6d338e1d', 3449 + 'aphront-tokenizer-control-css' => '6d338e1d', 3450 + 'aphront-tooltip-css' => '6d338e1d', 3451 + 'aphront-typeahead-control-css' => '6d338e1d', 3452 3452 'differential-changeset-view-css' => '380df740', 3453 3453 'differential-core-view-css' => '380df740', 3454 - 'differential-inline-comment-editor' => 'a8e8f2b7', 3454 + 'differential-inline-comment-editor' => '8b98837e', 3455 3455 'differential-local-commits-view-css' => '380df740', 3456 3456 'differential-results-table-css' => '380df740', 3457 3457 'differential-revision-add-comment-css' => '380df740', ··· 3462 3462 'differential-table-of-contents-css' => '380df740', 3463 3463 'diffusion-commit-view-css' => 'c8ce2d88', 3464 3464 'diffusion-icons-css' => 'c8ce2d88', 3465 - 'global-drag-and-drop-css' => '736c46dd', 3465 + 'global-drag-and-drop-css' => '6d338e1d', 3466 3466 'inline-comment-summary-css' => '380df740', 3467 3467 'javelin-aphlict' => '70c8162b', 3468 3468 'javelin-behavior' => 'db6d724d', 3469 3469 'javelin-behavior-aphlict-dropdown' => '70c8162b', 3470 3470 'javelin-behavior-aphlict-listen' => '70c8162b', 3471 3471 'javelin-behavior-aphront-basic-tokenizer' => '70c8162b', 3472 - 'javelin-behavior-aphront-drag-and-drop' => 'a8e8f2b7', 3473 - 'javelin-behavior-aphront-drag-and-drop-textarea' => 'a8e8f2b7', 3472 + 'javelin-behavior-aphront-drag-and-drop' => '8b98837e', 3473 + 'javelin-behavior-aphront-drag-and-drop-textarea' => '8b98837e', 3474 3474 'javelin-behavior-aphront-form-disable-on-submit' => '70c8162b', 3475 3475 'javelin-behavior-audit-preview' => '5e68be89', 3476 3476 'javelin-behavior-dark-console' => '8edbada5', 3477 3477 'javelin-behavior-dark-console-ajax' => '8edbada5', 3478 3478 'javelin-behavior-device' => '70c8162b', 3479 - 'javelin-behavior-differential-accept-with-errors' => 'a8e8f2b7', 3480 - 'javelin-behavior-differential-add-reviewers-and-ccs' => 'a8e8f2b7', 3481 - 'javelin-behavior-differential-comment-jump' => 'a8e8f2b7', 3482 - 'javelin-behavior-differential-diff-radios' => 'a8e8f2b7', 3483 - 'javelin-behavior-differential-dropdown-menus' => 'a8e8f2b7', 3484 - 'javelin-behavior-differential-edit-inline-comments' => 'a8e8f2b7', 3485 - 'javelin-behavior-differential-feedback-preview' => 'a8e8f2b7', 3486 - 'javelin-behavior-differential-keyboard-navigation' => 'a8e8f2b7', 3487 - 'javelin-behavior-differential-populate' => 'a8e8f2b7', 3488 - 'javelin-behavior-differential-show-more' => 'a8e8f2b7', 3489 - 'javelin-behavior-differential-toggle-files' => 'a8e8f2b7', 3490 - 'javelin-behavior-differential-user-select' => 'a8e8f2b7', 3479 + 'javelin-behavior-differential-accept-with-errors' => '8b98837e', 3480 + 'javelin-behavior-differential-add-reviewers-and-ccs' => '8b98837e', 3481 + 'javelin-behavior-differential-comment-jump' => '8b98837e', 3482 + 'javelin-behavior-differential-diff-radios' => '8b98837e', 3483 + 'javelin-behavior-differential-dropdown-menus' => '8b98837e', 3484 + 'javelin-behavior-differential-edit-inline-comments' => '8b98837e', 3485 + 'javelin-behavior-differential-feedback-preview' => '8b98837e', 3486 + 'javelin-behavior-differential-keyboard-navigation' => '8b98837e', 3487 + 'javelin-behavior-differential-populate' => '8b98837e', 3488 + 'javelin-behavior-differential-show-more' => '8b98837e', 3489 + 'javelin-behavior-differential-toggle-files' => '8b98837e', 3490 + 'javelin-behavior-differential-user-select' => '8b98837e', 3491 3491 'javelin-behavior-diffusion-commit-graph' => '5e68be89', 3492 3492 'javelin-behavior-diffusion-pull-lastmodified' => '5e68be89', 3493 3493 'javelin-behavior-error-log' => '8edbada5', ··· 3503 3503 'javelin-behavior-phabricator-autofocus' => '70c8162b', 3504 3504 'javelin-behavior-phabricator-keyboard-shortcuts' => '70c8162b', 3505 3505 'javelin-behavior-phabricator-nav' => '70c8162b', 3506 - 'javelin-behavior-phabricator-object-selector' => 'a8e8f2b7', 3506 + 'javelin-behavior-phabricator-object-selector' => '8b98837e', 3507 3507 'javelin-behavior-phabricator-oncopy' => '70c8162b', 3508 3508 'javelin-behavior-phabricator-remarkup-assist' => '70c8162b', 3509 3509 'javelin-behavior-phabricator-search-typeahead' => '70c8162b', 3510 3510 'javelin-behavior-phabricator-tooltips' => '70c8162b', 3511 3511 'javelin-behavior-phabricator-watch-anchor' => '70c8162b', 3512 3512 'javelin-behavior-refresh-csrf' => '70c8162b', 3513 - 'javelin-behavior-repository-crossreference' => 'a8e8f2b7', 3513 + 'javelin-behavior-repository-crossreference' => '8b98837e', 3514 3514 'javelin-behavior-toggle-class' => '70c8162b', 3515 3515 'javelin-behavior-workflow' => '70c8162b', 3516 3516 'javelin-dom' => 'db6d724d', ··· 3531 3531 'javelin-util' => 'db6d724d', 3532 3532 'javelin-vector' => 'db6d724d', 3533 3533 'javelin-workflow' => 'db6d724d', 3534 - 'lightbox-attachment-css' => '736c46dd', 3534 + 'lightbox-attachment-css' => '6d338e1d', 3535 3535 'maniphest-task-summary-css' => '7839ae2d', 3536 3536 'maniphest-transaction-detail-css' => '7839ae2d', 3537 - 'phabricator-app-buttons-css' => '736c46dd', 3537 + 'phabricator-app-buttons-css' => '6d338e1d', 3538 3538 'phabricator-busy' => '70c8162b', 3539 3539 'phabricator-content-source-view-css' => '380df740', 3540 - 'phabricator-core-buttons-css' => '736c46dd', 3541 - 'phabricator-core-css' => '736c46dd', 3542 - 'phabricator-crumbs-view-css' => '736c46dd', 3543 - 'phabricator-directory-css' => '736c46dd', 3544 - 'phabricator-drag-and-drop-file-upload' => 'a8e8f2b7', 3540 + 'phabricator-core-buttons-css' => '6d338e1d', 3541 + 'phabricator-core-css' => '6d338e1d', 3542 + 'phabricator-crumbs-view-css' => '6d338e1d', 3543 + 'phabricator-directory-css' => '6d338e1d', 3544 + 'phabricator-drag-and-drop-file-upload' => '8b98837e', 3545 3545 'phabricator-dropdown-menu' => '70c8162b', 3546 3546 'phabricator-file-upload' => '70c8162b', 3547 - 'phabricator-filetree-view-css' => '736c46dd', 3548 - 'phabricator-flag-css' => '736c46dd', 3549 - 'phabricator-form-view-css' => '736c46dd', 3550 - 'phabricator-header-view-css' => '736c46dd', 3551 - 'phabricator-jump-nav' => '736c46dd', 3547 + 'phabricator-filetree-view-css' => '6d338e1d', 3548 + 'phabricator-flag-css' => '6d338e1d', 3549 + 'phabricator-form-view-css' => '6d338e1d', 3550 + 'phabricator-header-view-css' => '6d338e1d', 3551 + 'phabricator-jump-nav' => '6d338e1d', 3552 3552 'phabricator-keyboard-shortcut' => '70c8162b', 3553 3553 'phabricator-keyboard-shortcut-manager' => '70c8162b', 3554 - 'phabricator-main-menu-view' => '736c46dd', 3554 + 'phabricator-main-menu-view' => '6d338e1d', 3555 3555 'phabricator-menu-item' => '70c8162b', 3556 - 'phabricator-nav-view-css' => '736c46dd', 3556 + 'phabricator-nav-view-css' => '6d338e1d', 3557 3557 'phabricator-notification' => '70c8162b', 3558 - 'phabricator-notification-css' => '736c46dd', 3559 - 'phabricator-notification-menu-css' => '736c46dd', 3560 - 'phabricator-object-item-list-view-css' => '736c46dd', 3558 + 'phabricator-notification-css' => '6d338e1d', 3559 + 'phabricator-notification-menu-css' => '6d338e1d', 3560 + 'phabricator-object-item-list-view-css' => '6d338e1d', 3561 3561 'phabricator-object-selector-css' => '380df740', 3562 3562 'phabricator-paste-file-upload' => '70c8162b', 3563 3563 'phabricator-prefab' => '70c8162b', 3564 3564 'phabricator-project-tag-css' => '7839ae2d', 3565 - 'phabricator-remarkup-css' => '736c46dd', 3566 - 'phabricator-shaped-request' => 'a8e8f2b7', 3567 - 'phabricator-side-menu-view-css' => '736c46dd', 3568 - 'phabricator-standard-page-view' => '736c46dd', 3565 + 'phabricator-remarkup-css' => '6d338e1d', 3566 + 'phabricator-shaped-request' => '8b98837e', 3567 + 'phabricator-side-menu-view-css' => '6d338e1d', 3568 + 'phabricator-standard-page-view' => '6d338e1d', 3569 3569 'phabricator-textareautils' => '70c8162b', 3570 3570 'phabricator-tooltip' => '70c8162b', 3571 - 'phabricator-transaction-view-css' => '736c46dd', 3572 - 'sprite-apps-large-css' => '736c46dd', 3573 - 'sprite-gradient-css' => '736c46dd', 3574 - 'sprite-icon-css' => '736c46dd', 3575 - 'sprite-menu-css' => '736c46dd', 3576 - 'syntax-highlighting-css' => '736c46dd', 3571 + 'phabricator-transaction-view-css' => '6d338e1d', 3572 + 'sprite-apps-large-css' => '6d338e1d', 3573 + 'sprite-gradient-css' => '6d338e1d', 3574 + 'sprite-icon-css' => '6d338e1d', 3575 + 'sprite-menu-css' => '6d338e1d', 3576 + 'syntax-highlighting-css' => '6d338e1d', 3577 3577 ), 3578 3578 ));
+14 -23
src/applications/drydock/controller/DrydockController.php
··· 2 2 3 3 abstract class DrydockController extends PhabricatorController { 4 4 5 - public function buildStandardPageResponse($view, array $data) { 6 - 7 - $page = $this->buildStandardPageView(); 8 - 9 - $page->setApplicationName('Drydock'); 10 - $page->setBaseURI('/drydock/'); 11 - $page->setTitle(idx($data, 'title')); 12 - $page->setGlyph("\xE2\x98\x82"); 13 - 14 - $page->appendChild($view); 15 - 16 - $response = new AphrontWebpageResponse(); 17 - return $response->setContent($page->render()); 18 - } 19 - 20 5 final protected function buildSideNav($selected) { 21 6 $nav = new AphrontSideNavFilterView(); 22 7 $nav->setBaseURI(new PhutilURI('/drydock/')); ··· 28 13 $nav->selectFilter($selected, 'resource'); 29 14 30 15 return $nav; 16 + } 17 + 18 + public function buildApplicationMenu() { 19 + return $this->buildSideNav(null)->getMenu(); 31 20 } 32 21 33 22 protected function buildLogTableView(array $logs) { ··· 35 24 36 25 $user = $this->getRequest()->getUser(); 37 26 38 - // TODO: It's probably a stretch to claim this works on mobile. 39 - 40 27 $rows = array(); 41 28 foreach ($logs as $log) { 42 29 $resource_uri = '/resource/'.$log->getResourceID().'/'; ··· 59 46 ), 60 47 phutil_escape_html($log->getLeaseID())), 61 48 phutil_escape_html($log->getMessage()), 62 - phabricator_datetime($log->getEpoch(), $user), 49 + phabricator_date($log->getEpoch(), $user), 63 50 ); 64 51 } 65 52 66 53 $table = new AphrontTableView($rows); 54 + $table->setDeviceReadyTable(true); 67 55 $table->setHeaders( 68 56 array( 69 57 'Resource', ··· 71 59 'Message', 72 60 'Date', 73 61 )); 62 + $table->setShortHeaders( 63 + array( 64 + 'R', 65 + 'L', 66 + 'Message', 67 + '', 68 + )); 74 69 $table->setColumnClasses( 75 70 array( 76 71 '', ··· 79 74 '', 80 75 )); 81 76 82 - $panel = new AphrontPanelView(); 83 - $panel->setHeader('Logs'); 84 - $panel->appendChild($table); 85 - 86 - return $panel; 77 + return $table; 87 78 } 88 79 89 80 protected function buildLeaseListView(array $leases) {
+21 -3
src/applications/drydock/controller/DrydockLogController.php
··· 27 27 28 28 $logs = $query->executeWithOffsetPager($pager); 29 29 30 + $title = pht('Logs'); 31 + 32 + $header = id(new PhabricatorHeaderView()) 33 + ->setHeader($title); 34 + 30 35 $table = $this->buildLogTableView($logs); 31 36 $table->appendChild($pager); 32 37 33 - $nav->appendChild($table); 38 + $nav->appendChild( 39 + array( 40 + $header, 41 + $table, 42 + $pager, 43 + )); 34 44 35 - return $this->buildStandardPageResponse( 45 + $crumbs = $this->buildApplicationCrumbs(); 46 + $crumbs->addCrumb( 47 + id(new PhabricatorCrumbView()) 48 + ->setName($title) 49 + ->setHref($this->getApplicationURI('/logs/'))); 50 + $nav->setCrumbs($crumbs); 51 + 52 + return $this->buildApplicationPage( 36 53 $nav, 37 54 array( 38 - 'title' => 'Logs', 55 + 'title' => $title, 56 + 'device' => true, 39 57 )); 40 58 41 59 }
+52
src/view/control/AphrontTableView.php
··· 4 4 5 5 protected $data; 6 6 protected $headers; 7 + protected $shortHeaders; 7 8 protected $rowClasses = array(); 8 9 protected $columnClasses = array(); 9 10 protected $cellClasses = array(); ··· 11 12 protected $noDataString; 12 13 protected $className; 13 14 protected $columnVisibility = array(); 15 + private $deviceVisibility = array(); 14 16 15 17 protected $sortURI; 16 18 protected $sortParam; 17 19 protected $sortSelected; 18 20 protected $sortReverse; 19 21 protected $sortValues; 22 + private $deviceReadyTable; 20 23 21 24 public function __construct(array $data) { 22 25 $this->data = $data; ··· 62 65 return $this; 63 66 } 64 67 68 + public function setDeviceVisibility(array $device_visibility) { 69 + $this->deviceVisibility = $device_visibility; 70 + return $this; 71 + } 72 + 73 + public function setDeviceReadyTable($ready) { 74 + $this->deviceReadyTable = $ready; 75 + return $this; 76 + } 77 + 78 + public function setShortHeaders(array $short_headers) { 79 + $this->shortHeaders = $short_headers; 80 + return $this; 81 + } 82 + 65 83 /** 66 84 * Parse a sorting parameter: 67 85 * ··· 94 112 require_celerity_resource('aphront-table-view-css'); 95 113 96 114 $table_class = $this->className; 115 + 116 + if ($this->deviceReadyTable) { 117 + $table_class .= ' aphront-table-view-device-ready'; 118 + } 119 + 97 120 if ($table_class !== null) { 98 121 $table_class = ' class="aphront-table-view '.$table_class.'"'; 99 122 } else { ··· 111 134 } 112 135 113 136 $visibility = array_values($this->columnVisibility); 137 + $device_visibility = array_values($this->deviceVisibility); 114 138 $headers = $this->headers; 139 + $short_headers = $this->shortHeaders; 115 140 $sort_values = $this->sortValues; 116 141 if ($headers) { 117 142 while (count($headers) > count($visibility)) { 118 143 $visibility[] = true; 119 144 } 145 + while (count($headers) > count($device_visibility)) { 146 + $device_visibility[] = true; 147 + } 148 + while (count($headers) > count($short_headers)) { 149 + $short_headers[] = null; 150 + } 120 151 while (count($headers) > count($sort_values)) { 121 152 $sort_values[] = null; 122 153 } ··· 130 161 131 162 if (!empty($col_classes[$col_num])) { 132 163 $classes[] = $col_classes[$col_num]; 164 + } 165 + 166 + if (empty($device_visiblity[$col_num])) { 167 + $classes[] = 'aphront-table-nodevice'; 133 168 } 134 169 135 170 if ($sort_values[$col_num] !== null) { ··· 166 201 $class = ' class="'.implode(' ', $classes).'"'; 167 202 } else { 168 203 $class = null; 204 + } 205 + 206 + if ($short_headers[$col_num] !== null) { 207 + $header_nodevice = phutil_render_tag( 208 + 'span', 209 + array( 210 + 'class' => 'aphront-table-view-nodevice', 211 + ), 212 + $header); 213 + $header_device = phutil_render_tag( 214 + 'span', 215 + array( 216 + 'class' => 'aphront-table-view-device', 217 + ), 218 + phutil_escape_html($short_headers[$col_num])); 219 + 220 + $header = $header_nodevice.$header_device; 169 221 } 170 222 171 223 $table[] = '<th'.$class.'>'.$header.'</th>';
+62 -2
webroot/rsrc/css/aphront/table-view.css
··· 16 16 .aphront-table-view th { 17 17 font-size: 12px; 18 18 font-weight: bold; 19 - padding: 4px 8px; 20 19 background: #003366; 21 20 color: white; 22 21 white-space: nowrap; ··· 44 43 } 45 44 46 45 .aphront-table-view td { 47 - padding: 4px 8px; 48 46 font-size: 11px; 49 47 white-space: nowrap; 50 48 vertical-align: middle; 49 + } 50 + 51 + /* - Padding ------------------------------------------------------------------- 52 + 53 + On desktops, we have more horizontal space and use it to space columns out. 54 + 55 + On devices, we make each row slightly taller to create a larger hit target 56 + for links. 57 + 58 + */ 59 + 60 + .aphront-table-view th { 61 + padding: 4px 8px; 62 + } 63 + 64 + .aphront-table-view td { 65 + padding: 4px 8px; 66 + } 67 + 68 + .device-tablet .aphront-table-view td, 69 + .device-phone .aphront-table-view td { 70 + padding: 6px; 71 + } 72 + 73 + .device-tablet .aphront-table-view td + td, 74 + .device-phone .aphront-table-view td + td { 75 + padding-left: 0px; 76 + } 77 + 78 + .device-tablet .aphront-table-view th, 79 + .device-phone .aphront-table-view th { 80 + padding: 6px; 81 + overflow: hidden; 82 + } 83 + 84 + .device-tablet .aphront-table-view th + th, 85 + .device-phone .aphront-table-view th + th { 86 + padding-left: 0px; 51 87 } 52 88 53 89 .aphront-table-view td.sorted-column { ··· 164 200 display: block; 165 201 color: white; 166 202 } 203 + 204 + .device-desktop .aphront-table-view-device { 205 + display: none; 206 + } 207 + 208 + .device-tablet .aphront-table-view-nodevice, 209 + .device-phone .aphront-table-view-nodevice { 210 + display: none; 211 + } 212 + 213 + .aphront-table-view-device-ready { 214 + width: 99%; 215 + margin: 8px auto; 216 + } 217 + 218 + .aphront-table-view td.link { 219 + padding: 0; 220 + } 221 + 222 + .aphront-table-view td.link a { 223 + display: block; 224 + padding: 6px; 225 + font-weight: bold; 226 + }