@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.

Revamp Projects with new navigation

Summary:
A refresh of Projects including a new navigations UI.

- New Navigation UI.
- Auto switch default page if Workboard has been initialized
- Move Feed to it's own page
- Increase 'tasks' on Project Home to 50 over 10
- Fix various display bugs on Workboards
- Remove 'crumbs' from Project portal (unneeded).

Test Plan:
- clicked a link for a project with no workboard and saw the profile
- clicked a link for a project with a workboard and saw the workboard
- navigated around the various edit pages, inspecting links and making sure things linked back to the new profile uri

{F266460}

{F266461}

{F266462}

{F266463}

{F266464}

Reviewers: epriestley, btrahan

Reviewed By: epriestley, btrahan

Subscribers: Korvin, epriestley

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

+466 -246
+11 -11
resources/celerity/map.php
··· 7 7 */ 8 8 return array( 9 9 'names' => array( 10 - 'core.pkg.css' => 'b99369cc', 10 + 'core.pkg.css' => '60a6d241', 11 11 'core.pkg.js' => '61af8961', 12 12 'darkconsole.pkg.js' => '8ab24e01', 13 13 'differential.pkg.css' => '8af45893', ··· 23 23 'rsrc/css/aphront/error-view.css' => '3462dbee', 24 24 'rsrc/css/aphront/lightbox-attachment.css' => '7acac05d', 25 25 'rsrc/css/aphront/list-filter-view.css' => '2ae43867', 26 - 'rsrc/css/aphront/multi-column.css' => '6d72e772', 26 + 'rsrc/css/aphront/multi-column.css' => '41a848c0', 27 27 'rsrc/css/aphront/notification.css' => '9c279160', 28 28 'rsrc/css/aphront/pager-view.css' => '2e3539af', 29 29 'rsrc/css/aphront/panel-view.css' => '5846dfa2', ··· 94 94 'rsrc/css/application/ponder/feed.css' => 'e62615b6', 95 95 'rsrc/css/application/ponder/post.css' => 'ebab8a70', 96 96 'rsrc/css/application/ponder/vote.css' => '8ed6ed8b', 97 - 'rsrc/css/application/profile/profile-view.css' => '28f433ef', 97 + 'rsrc/css/application/profile/profile-view.css' => 'fddedfa1', 98 98 'rsrc/css/application/projects/project-icon.css' => 'c2ecb7f1', 99 99 'rsrc/css/application/releeph/releeph-core.css' => '9b3c5733', 100 100 'rsrc/css/application/releeph/releeph-preview-branch.css' => 'b7a6f4a5', ··· 115 115 'rsrc/css/layout/phabricator-crumbs-view.css' => 'd5aa87e4', 116 116 'rsrc/css/layout/phabricator-filetree-view.css' => 'fccf9f82', 117 117 'rsrc/css/layout/phabricator-hovercard-view.css' => '893f4783', 118 - 'rsrc/css/layout/phabricator-side-menu-view.css' => '90eafc85', 118 + 'rsrc/css/layout/phabricator-side-menu-view.css' => '7e8c6341', 119 119 'rsrc/css/layout/phabricator-source-code-view.css' => '7d346aa4', 120 120 'rsrc/css/phui/calendar/phui-calendar-day.css' => 'de035c8a', 121 121 'rsrc/css/phui/calendar/phui-calendar-list.css' => 'c1d0ca59', ··· 136 136 'rsrc/css/phui/phui-info-panel.css' => '27ea50a1', 137 137 'rsrc/css/phui/phui-list.css' => '53deb25c', 138 138 'rsrc/css/phui/phui-object-box.css' => 'dd19785f', 139 - 'rsrc/css/phui/phui-object-item-list-view.css' => '5b2ad99d', 139 + 'rsrc/css/phui/phui-object-item-list-view.css' => '8279b873', 140 140 'rsrc/css/phui/phui-pinboard-view.css' => '3dd4a269', 141 141 'rsrc/css/phui/phui-property-list-view.css' => '51480060', 142 142 'rsrc/css/phui/phui-remarkup-preview.css' => '19ad512b', ··· 145 145 'rsrc/css/phui/phui-tag-view.css' => '6b74282b', 146 146 'rsrc/css/phui/phui-text.css' => 'cf019f54', 147 147 'rsrc/css/phui/phui-timeline-view.css' => '415bf348', 148 - 'rsrc/css/phui/phui-workboard-view.css' => '2bf82d00', 148 + 'rsrc/css/phui/phui-workboard-view.css' => '8896938c', 149 149 'rsrc/css/phui/phui-workpanel-view.css' => 'e495a5cc', 150 150 'rsrc/css/sprite-apps-large.css' => '20ec0cc0', 151 151 'rsrc/css/sprite-apps.css' => 'd5baed0f', ··· 498 498 'aphront-dialog-view-css' => '4dbbe3bb', 499 499 'aphront-error-view-css' => '3462dbee', 500 500 'aphront-list-filter-view-css' => '2ae43867', 501 - 'aphront-multi-column-view-css' => '6d72e772', 501 + 'aphront-multi-column-view-css' => '41a848c0', 502 502 'aphront-pager-view-css' => '2e3539af', 503 503 'aphront-panel-view-css' => '5846dfa2', 504 504 'aphront-table-view-css' => 'b22b7216', ··· 728 728 'phabricator-object-selector-css' => '029a133d', 729 729 'phabricator-phtize' => 'd254d646', 730 730 'phabricator-prefab' => '72da38cc', 731 - 'phabricator-profile-css' => '28f433ef', 731 + 'phabricator-profile-css' => 'fddedfa1', 732 732 'phabricator-remarkup-css' => '7604f12e', 733 733 'phabricator-search-results-css' => 'f240504c', 734 734 'phabricator-shaped-request' => '7cbe244b', 735 - 'phabricator-side-menu-view-css' => '90eafc85', 735 + 'phabricator-side-menu-view-css' => '7e8c6341', 736 736 'phabricator-slowvote-css' => '266df6a1', 737 737 'phabricator-source-code-view-css' => '7d346aa4', 738 738 'phabricator-standard-page-view' => '2c96cfb5', ··· 780 780 'phui-info-panel-css' => '27ea50a1', 781 781 'phui-list-view-css' => '53deb25c', 782 782 'phui-object-box-css' => 'dd19785f', 783 - 'phui-object-item-list-view-css' => '5b2ad99d', 783 + 'phui-object-item-list-view-css' => '8279b873', 784 784 'phui-pinboard-view-css' => '3dd4a269', 785 785 'phui-property-list-view-css' => '51480060', 786 786 'phui-remarkup-preview-css' => '19ad512b', ··· 789 789 'phui-tag-view-css' => '6b74282b', 790 790 'phui-text-css' => 'cf019f54', 791 791 'phui-timeline-view-css' => '415bf348', 792 - 'phui-workboard-view-css' => '2bf82d00', 792 + 'phui-workboard-view-css' => '8896938c', 793 793 'phui-workpanel-view-css' => 'e495a5cc', 794 794 'phuix-action-list-view' => 'b5c256b8', 795 795 'phuix-action-view' => '6e8cefa4',
+4
src/__phutil_library_map__.php
··· 2199 2199 'PhabricatorProjectEditMainController' => 'applications/project/controller/PhabricatorProjectEditMainController.php', 2200 2200 'PhabricatorProjectEditPictureController' => 'applications/project/controller/PhabricatorProjectEditPictureController.php', 2201 2201 'PhabricatorProjectEditorTestCase' => 'applications/project/editor/__tests__/PhabricatorProjectEditorTestCase.php', 2202 + 'PhabricatorProjectFeedController' => 'applications/project/controller/PhabricatorProjectFeedController.php', 2202 2203 'PhabricatorProjectIcon' => 'applications/project/icon/PhabricatorProjectIcon.php', 2203 2204 'PhabricatorProjectInterface' => 'applications/project/interface/PhabricatorProjectInterface.php', 2204 2205 'PhabricatorProjectListController' => 'applications/project/controller/PhabricatorProjectListController.php', ··· 2225 2226 'PhabricatorProjectTransactionQuery' => 'applications/project/query/PhabricatorProjectTransactionQuery.php', 2226 2227 'PhabricatorProjectUIEventListener' => 'applications/project/events/PhabricatorProjectUIEventListener.php', 2227 2228 'PhabricatorProjectUpdateController' => 'applications/project/controller/PhabricatorProjectUpdateController.php', 2229 + 'PhabricatorProjectViewController' => 'applications/project/controller/PhabricatorProjectViewController.php', 2228 2230 'PhabricatorProjectWatchController' => 'applications/project/controller/PhabricatorProjectWatchController.php', 2229 2231 'PhabricatorProjectWikiExplainController' => 'applications/project/controller/PhabricatorProjectWikiExplainController.php', 2230 2232 'PhabricatorProjectsPolicyRule' => 'applications/policy/rule/PhabricatorProjectsPolicyRule.php', ··· 5418 5420 'PhabricatorProjectEditMainController' => 'PhabricatorProjectController', 5419 5421 'PhabricatorProjectEditPictureController' => 'PhabricatorProjectController', 5420 5422 'PhabricatorProjectEditorTestCase' => 'PhabricatorTestCase', 5423 + 'PhabricatorProjectFeedController' => 'PhabricatorProjectController', 5421 5424 'PhabricatorProjectIcon' => 'Phobject', 5422 5425 'PhabricatorProjectListController' => 'PhabricatorProjectController', 5423 5426 'PhabricatorProjectMemberOfProjectEdgeType' => 'PhabricatorEdgeType', ··· 5445 5448 'PhabricatorProjectTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 5446 5449 'PhabricatorProjectUIEventListener' => 'PhabricatorEventListener', 5447 5450 'PhabricatorProjectUpdateController' => 'PhabricatorProjectController', 5451 + 'PhabricatorProjectViewController' => 'PhabricatorProjectController', 5448 5452 'PhabricatorProjectWatchController' => 'PhabricatorProjectController', 5449 5453 'PhabricatorProjectWikiExplainController' => 'PhabricatorProjectController', 5450 5454 'PhabricatorProjectsPolicyRule' => 'PhabricatorPolicyRule',
+6 -2
src/applications/project/application/PhabricatorProjectApplication.php
··· 52 52 => 'PhabricatorProjectMembersEditController', 53 53 'members/(?P<id>[1-9]\d*)/remove/' 54 54 => 'PhabricatorProjectMembersRemoveController', 55 - 'view/(?P<id>[1-9]\d*)/' 55 + 'profile/(?P<id>[1-9]\d*)/' 56 56 => 'PhabricatorProjectProfileController', 57 + 'feed/(?P<id>[1-9]\d*)/' 58 + => 'PhabricatorProjectFeedController', 59 + 'view/(?P<id>[1-9]\d*)/' 60 + => 'PhabricatorProjectViewController', 57 61 'picture/(?P<id>[1-9]\d*)/' 58 62 => 'PhabricatorProjectEditPictureController', 59 63 'icon/(?P<id>[1-9]\d*)/' ··· 86 90 'wiki/' => 'PhabricatorProjectWikiExplainController', 87 91 ), 88 92 '/tag/' => array( 89 - '(?P<slug>[^/]+)/' => 'PhabricatorProjectProfileController', 93 + '(?P<slug>[^/]+)/' => 'PhabricatorProjectViewController', 90 94 '(?P<slug>[^/]+)/board/' => 'PhabricatorProjectBoardViewController', 91 95 ), 92 96 );
+5 -7
src/applications/project/controller/PhabricatorProjectBoardController.php
··· 13 13 return $this->project; 14 14 } 15 15 16 - protected function buildApplicationCrumbs() { 17 - $project = $this->getProject(); 18 - $crumbs = parent::buildApplicationCrumbs(); 19 - $crumbs->addTextCrumb( 20 - $project->getName(), 21 - $this->getApplicationURI('view/'.$project->getID().'/')); 22 - return $crumbs; 16 + public function buildIconNavView(PhabricatorProject $project) { 17 + $id = $project->getID(); 18 + $nav = parent::buildIconNavView($project); 19 + $nav->selectFilter("board/{$id}/"); 20 + return $nav; 23 21 } 24 22 }
+16 -18
src/applications/project/controller/PhabricatorProjectBoardViewController.php
··· 15 15 return true; 16 16 } 17 17 18 - public function willProcessRequest(array $data) { 19 - $this->id = idx($data, 'id'); 20 - $this->slug = idx($data, 'slug'); 21 - $this->queryKey = idx($data, 'queryKey'); 22 - $this->filter = (bool)idx($data, 'filter'); 23 - } 24 - 25 - public function processRequest() { 26 - $request = $this->getRequest(); 18 + public function handleRequest(AphrontRequest $request) { 27 19 $viewer = $request->getUser(); 20 + $id = $request->getURIData('id'); 28 21 29 22 $show_hidden = $request->getBool('hidden'); 30 23 $this->showHidden = $show_hidden; ··· 32 25 $project = id(new PhabricatorProjectQuery()) 33 26 ->setViewer($viewer) 34 27 ->needImages(true); 35 - if ($this->slug) { 36 - $project->withSlugs(array($this->slug)); 28 + $id = $request->getURIData('id'); 29 + $slug = $request->getURIData('slug'); 30 + if ($slug) { 31 + $project->withSlugs(array($slug)); 37 32 } else { 38 - $project->withIDs(array($this->id)); 33 + $project->withIDs(array($id)); 39 34 } 40 35 $project = $project->executeOne(); 41 36 if (!$project) { ··· 111 106 $engine->getQueryResultsPageURI($saved->getQueryKey()))); 112 107 } 113 108 114 - $query_key = $this->queryKey; 109 + $query_key = $request->getURIData('queryKey'); 115 110 if (!$query_key) { 116 111 $query_key = 'open'; 117 112 } ··· 133 128 $custom_query = $saved; 134 129 } 135 130 136 - if ($this->filter) { 131 + if ($request->getURIData('filter')) { 137 132 $filter_form = id(new AphrontFormView()) 138 133 ->setUser($viewer); 139 134 $engine->buildSearchForm($filter_form, $saved); ··· 303 298 $header_link = phutil_tag( 304 299 'a', 305 300 array( 306 - 'href' => $this->getApplicationURI('view/'.$project->getID().'/'), 301 + 'href' => $this->getApplicationURI('profile/'.$project->getID().'/'), 307 302 ), 308 303 $project->getName()); 309 304 ··· 312 307 ->setUser($viewer) 313 308 ->setNoBackground(true) 314 309 ->setImage($project->getProfileImageURI()) 315 - ->setImageURL($this->getApplicationURI('view/'.$project->getID().'/')) 310 + ->setImageURL($this->getApplicationURI('profile/'.$project->getID().'/')) 316 311 ->addActionLink($sort_menu) 317 312 ->addActionLink($filter_menu) 318 313 ->addActionLink($manage_menu) ··· 322 317 ->appendChild($board) 323 318 ->addClass('project-board-wrapper'); 324 319 320 + $nav = $this->buildIconNavView($project); 321 + $nav->appendChild($header); 322 + $nav->appendChild($board_box); 323 + 325 324 return $this->buildApplicationPage( 326 325 array( 327 - $header, 328 - $board_box, 326 + $nav, 329 327 ), 330 328 array( 331 329 'title' => pht('%s Board', $project->getName()),
+6 -8
src/applications/project/controller/PhabricatorProjectColumnDetailController.php
··· 22 22 PhabricatorPolicyCapability::CAN_VIEW, 23 23 )) 24 24 ->withIDs(array($this->projectID)) 25 + ->needImages(true) 25 26 ->executeOne(); 26 27 27 28 if (!$project) { ··· 47 48 $timeline->setShouldTerminate(true); 48 49 49 50 $title = pht('%s', $column->getDisplayName()); 50 - $crumbs = $this->buildApplicationCrumbs(); 51 - $crumbs->addTextCrumb( 52 - pht('Board'), 53 - $this->getApplicationURI('board/'.$project->getID().'/')); 54 - $crumbs->addTextCrumb($title); 55 51 56 52 $header = $this->buildHeaderView($column); 57 53 $actions = $this->buildActionView($column); ··· 61 57 ->setHeader($header) 62 58 ->addPropertyList($properties); 63 59 60 + $nav = $this->buildIconNavView($project); 61 + $nav->appendChild($box); 62 + $nav->appendChild($timeline); 63 + 64 64 return $this->buildApplicationPage( 65 65 array( 66 - $crumbs, 67 - $box, 68 - $timeline, 66 + $nav, 69 67 ), 70 68 array( 71 69 'title' => $title,
+5 -17
src/applications/project/controller/PhabricatorProjectColumnEditController.php
··· 23 23 PhabricatorPolicyCapability::CAN_EDIT, 24 24 )) 25 25 ->withIDs(array($this->projectID)) 26 + ->needImages(true) 26 27 ->executeOne(); 27 28 28 29 if (!$project) { ··· 135 136 if ($is_new) { 136 137 $title = pht('Create Column'); 137 138 $submit = pht('Create Column'); 138 - $crumb_text = pht('Create Column'); 139 139 } else { 140 140 $title = pht('Edit %s', $column->getDisplayName()); 141 141 $submit = pht('Save Column'); 142 - $crumb_text = pht('Edit'); 143 142 } 144 143 145 144 $form->appendChild( ··· 147 146 ->setValue($submit) 148 147 ->addCancelButton($view_uri)); 149 148 150 - $crumbs = $this->buildApplicationCrumbs(); 151 - $crumbs->addTextCrumb( 152 - pht('Board'), 153 - $this->getApplicationURI('board/'.$project->getID().'/')); 154 - 155 - if (!$is_new) { 156 - $crumbs->addTextCrumb( 157 - $column->getDisplayName(), 158 - $view_uri); 159 - } 160 - 161 - $crumbs->addTextCrumb($crumb_text); 162 - 163 149 $form_box = id(new PHUIObjectBoxView()) 164 150 ->setHeaderText($title) 165 151 ->setValidationException($validation_exception) 166 152 ->setForm($form); 167 153 154 + $nav = $this->buildIconNavView($project); 155 + $nav->appendChild($form_box); 156 + 168 157 return $this->buildApplicationPage( 169 158 array( 170 - $crumbs, 171 - $form_box, 159 + $nav, 172 160 ), 173 161 array( 174 162 'title' => $title,
+36 -3
src/applications/project/controller/PhabricatorProjectController.php
··· 2 2 3 3 abstract class PhabricatorProjectController extends PhabricatorController { 4 4 5 + public function buildApplicationMenu() { 6 + return $this->buildSideNavView(true)->getMenu(); 7 + } 8 + 5 9 public function buildSideNavView($for_app = false) { 6 10 $user = $this->getRequest()->getUser(); 7 11 8 12 $nav = new AphrontSideNavFilterView(); 9 13 $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); 10 14 15 + $id = null; 11 16 if ($for_app) { 17 + $user = $this->getRequest()->getUser(); 18 + $id = $this->getRequest()->getURIData('id'); 19 + if ($id) { 20 + $nav->addFilter("profile/{$id}/", pht('Profile')); 21 + $nav->addFilter("board/{$id}/", pht('Workboard')); 22 + $nav->addFilter("members/{$id}/", pht('Members')); 23 + $nav->addFilter("feed/{$id}/", pht('Feed')); 24 + $nav->addFilter("edit/{$id}/", pht('Edit')); 25 + } 12 26 $nav->addFilter('create', pht('Create Project')); 13 27 } 14 28 15 - id(new PhabricatorProjectSearchEngine()) 16 - ->setViewer($user) 17 - ->addNavigationItems($nav->getMenu()); 29 + if (!$id) { 30 + id(new PhabricatorProjectSearchEngine()) 31 + ->setViewer($user) 32 + ->addNavigationItems($nav->getMenu()); 33 + } 18 34 19 35 $nav->selectFilter(null); 36 + 37 + return $nav; 38 + } 39 + 40 + public function buildIconNavView(PhabricatorProject $project) { 41 + $id = $project->getID(); 42 + $picture = $project->getProfileImageURI(); 43 + $name = $project->getName(); 44 + 45 + $nav = new AphrontSideNavFilterView(); 46 + $nav->setIconNav(true); 47 + $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); 48 + $nav->addIcon("profile/{$id}/", $name, null, $picture); 49 + $nav->addIcon("board/{$id}/", pht('Workboard'), 'fa-columns'); 50 + $nav->addIcon("feed/{$id}/", pht('Feed'), 'fa-newspaper-o'); 51 + $nav->addIcon("members/{$id}/", pht('Members'), 'fa-group'); 52 + $nav->addIcon("edit/{$id}/", pht('Edit'), 'fa-pencil'); 20 53 21 54 return $nav; 22 55 }
+10 -13
src/applications/project/controller/PhabricatorProjectEditDetailsController.php
··· 14 14 $viewer = $request->getUser(); 15 15 16 16 if ($this->id) { 17 - $is_new = false; 17 + $id = $request->getURIData('id'); 18 + $is_new = false; 18 19 19 20 $project = id(new PhabricatorProjectQuery()) 20 21 ->setViewer($viewer) 21 22 ->withIDs(array($this->id)) 22 23 ->needSlugs(true) 24 + ->needImages(true) 23 25 ->requireCapabilities( 24 26 array( 25 27 PhabricatorPolicyCapability::CAN_VIEW, ··· 149 151 150 152 if ($is_new) { 151 153 $redirect_uri = 152 - $this->getApplicationURI('view/'.$project->getID().'/'); 154 + $this->getApplicationURI('profile/'.$project->getID().'/'); 153 155 } else { 154 156 $redirect_uri = 155 157 $this->getApplicationURI('edit/'.$project->getID().'/'); ··· 300 302 ->setValidationException($validation_exception) 301 303 ->setForm($form); 302 304 303 - $crumbs = $this->buildApplicationCrumbs($this->buildSideNavView()); 304 - if ($is_new) { 305 - $crumbs->addTextCrumb($title); 305 + if (!$is_new) { 306 + $nav = $this->buildIconNavView($project); 307 + $nav->selectFilter("edit/{$id}/"); 308 + $nav->appendChild($form_box); 306 309 } else { 307 - $crumbs 308 - ->addTextCrumb($project->getName(), 309 - $this->getApplicationURI('view/'.$project->getID().'/')) 310 - ->addTextCrumb(pht('Edit'), 311 - $this->getApplicationURI('edit/'.$project->getID().'/')) 312 - ->addTextCrumb(pht('Details')); 310 + $nav = array($form_box); 313 311 } 314 312 315 313 return $this->buildApplicationPage( 316 314 array( 317 - $crumbs, 318 - $form_box, 315 + $nav, 319 316 ), 320 317 array( 321 318 'title' => $title,
+9 -9
src/applications/project/controller/PhabricatorProjectEditMainController.php
··· 18 18 public function processRequest() { 19 19 $request = $this->getRequest(); 20 20 $viewer = $request->getUser(); 21 + $id = $request->getURIData('id'); 21 22 22 23 $project = id(new PhabricatorProjectQuery()) 23 24 ->setViewer($viewer) ··· 43 44 $actions = $this->buildActionListView($project); 44 45 $properties = $this->buildPropertyListView($project, $actions); 45 46 46 - $crumbs = $this->buildApplicationCrumbs(); 47 - $crumbs->addTextCrumb( 48 - $project->getName(), 49 - $this->getApplicationURI('view/'.$project->getID().'/')); 50 - $crumbs->addTextCrumb(pht('Edit')); 51 - 52 47 $object_box = id(new PHUIObjectBoxView()) 53 48 ->setHeader($header) 54 49 ->addPropertyList($properties); ··· 58 53 new PhabricatorProjectTransactionQuery()); 59 54 $timeline->setShouldTerminate(true); 60 55 56 + $nav = $this->buildIconNavView($project); 57 + $nav->selectFilter("edit/{$id}/"); 58 + $nav->appendChild($object_box); 59 + $nav->appendChild($timeline); 60 + 61 + $mnav = $this->buildSideNavView(); 62 + 61 63 return $this->buildApplicationPage( 62 64 array( 63 - $crumbs, 64 - $object_box, 65 - $timeline, 65 + $nav, 66 66 ), 67 67 array( 68 68 'title' => $project->getName(),
+9 -8
src/applications/project/controller/PhabricatorProjectEditPictureController.php
··· 12 12 public function processRequest() { 13 13 $request = $this->getRequest(); 14 14 $viewer = $request->getUser(); 15 + $id = $request->getURIData('id'); 15 16 16 17 $project = id(new PhabricatorProjectQuery()) 17 18 ->setViewer($viewer) 18 19 ->withIDs(array($this->id)) 20 + ->needImages(true) 19 21 ->requireCapabilities( 20 22 array( 21 23 PhabricatorPolicyCapability::CAN_VIEW, ··· 27 29 } 28 30 29 31 $edit_uri = $this->getApplicationURI('edit/'.$project->getID().'/'); 30 - $view_uri = $this->getApplicationURI('view/'.$project->getID().'/'); 32 + $view_uri = $this->getApplicationURI('profile/'.$project->getID().'/'); 31 33 32 34 $supported_formats = PhabricatorFile::getTransformableImageFormats(); 33 35 $e_file = true; ··· 100 102 } 101 103 102 104 $title = pht('Edit Project Picture'); 103 - $crumbs = $this->buildApplicationCrumbs(); 104 - $crumbs->addTextCrumb($project->getName(), $view_uri); 105 - $crumbs->addTextCrumb(pht('Edit'), $edit_uri); 106 - $crumbs->addTextCrumb(pht('Picture')); 107 105 108 106 $form = id(new PHUIFormLayoutView()) 109 107 ->setUser($viewer); ··· 292 290 ->setHeaderText(pht('Upload New Picture')) 293 291 ->setForm($upload_form); 294 292 293 + $nav = $this->buildIconNavView($project); 294 + $nav->selectFilter("edit/{$id}/"); 295 + $nav->appendChild($form_box); 296 + $nav->appendChild($upload_box); 297 + 295 298 return $this->buildApplicationPage( 296 299 array( 297 - $crumbs, 298 - $form_box, 299 - $upload_box, 300 + $nav, 300 301 ), 301 302 array( 302 303 'title' => $title,
+91
src/applications/project/controller/PhabricatorProjectFeedController.php
··· 1 + <?php 2 + 3 + final class PhabricatorProjectFeedController 4 + extends PhabricatorProjectController { 5 + 6 + public function shouldAllowPublic() { 7 + return true; 8 + } 9 + 10 + public function handleRequest(AphrontRequest $request) { 11 + $user = $request->getUser(); 12 + 13 + $query = id(new PhabricatorProjectQuery()) 14 + ->setViewer($user) 15 + ->needMembers(true) 16 + ->needWatchers(true) 17 + ->needImages(true) 18 + ->needSlugs(true); 19 + $id = $request->getURIData('id'); 20 + $slug = $request->getURIData('slug'); 21 + if ($slug) { 22 + $query->withSlugs(array($slug)); 23 + } else { 24 + $query->withIDs(array($id)); 25 + } 26 + $project = $query->executeOne(); 27 + if (!$project) { 28 + return new Aphront404Response(); 29 + } 30 + if ($slug && $slug != $project->getPrimarySlug()) { 31 + return id(new AphrontRedirectResponse()) 32 + ->setURI('/tag/'.$project->getPrimarySlug().'/'); 33 + } 34 + 35 + require_celerity_resource('phabricator-profile-css'); 36 + 37 + $query = new PhabricatorFeedQuery(); 38 + $query->setFilterPHIDs( 39 + array( 40 + $project->getPHID(), 41 + )); 42 + $query->setLimit(50); 43 + $query->setViewer($request->getUser()); 44 + $stories = $query->execute(); 45 + $feed = $this->renderStories($stories); 46 + 47 + $content = phutil_tag_div('phabricator-project-feed', $feed); 48 + 49 + $nav = $this->buildIconNavView($project); 50 + $nav->selectFilter("feed/{$id}/"); 51 + $nav->appendChild($content); 52 + 53 + return $this->buildApplicationPage( 54 + array( 55 + $nav, 56 + ), 57 + array( 58 + 'title' => $project->getName(), 59 + )); 60 + } 61 + 62 + private function renderFeedPage(PhabricatorProject $project) { 63 + 64 + $query = new PhabricatorFeedQuery(); 65 + $query->setFilterPHIDs(array($project->getPHID())); 66 + $query->setViewer($this->getRequest()->getUser()); 67 + $query->setLimit(100); 68 + $stories = $query->execute(); 69 + 70 + if (!$stories) { 71 + return pht('There are no stories about this project.'); 72 + } 73 + 74 + return $this->renderStories($stories); 75 + } 76 + 77 + private function renderStories(array $stories) { 78 + assert_instances_of($stories, 'PhabricatorFeedStory'); 79 + 80 + $builder = new PhabricatorFeedBuilder($stories); 81 + $builder->setUser($this->getRequest()->getUser()); 82 + $builder->setShowHovercards(true); 83 + $view = $builder->buildView(); 84 + 85 + return phutil_tag_div( 86 + 'profile-feed', 87 + $view->render()); 88 + } 89 + 90 + 91 + }
+1 -1
src/applications/project/controller/PhabricatorProjectListController.php
··· 22 22 return $this->delegateToController($controller); 23 23 } 24 24 25 - protected function buildApplicationMenu() { 25 + public function buildApplicationMenu() { 26 26 return $this->buildSideNavView(true)->getMenu(); 27 27 } 28 28
+53 -35
src/applications/project/controller/PhabricatorProjectMembersEditController.php
··· 12 12 public function processRequest() { 13 13 $request = $this->getRequest(); 14 14 $user = $request->getUser(); 15 + $id = $request->getURIData('id'); 15 16 16 17 $project = id(new PhabricatorProjectQuery()) 17 18 ->setViewer($user) 18 19 ->withIDs(array($this->id)) 19 20 ->needMembers(true) 21 + ->needImages(true) 20 22 ->requireCapabilities( 21 23 array( 22 24 PhabricatorPolicyCapability::CAN_VIEW, 23 - PhabricatorPolicyCapability::CAN_EDIT, 24 25 )) 25 26 ->executeOne(); 26 27 if (!$project) { ··· 73 74 ); 74 75 } 75 76 76 - $header_name = pht('Edit Members'); 77 - $title = pht('Edit Members'); 77 + $can_edit = PhabricatorPolicyFilter::hasCapability( 78 + $user, 79 + $project, 80 + PhabricatorPolicyCapability::CAN_EDIT); 78 81 79 - $form = new AphrontFormView(); 80 - $form 81 - ->setUser($user) 82 - ->appendChild( 83 - id(new AphrontFormTokenizerControl()) 84 - ->setName('phids') 85 - ->setLabel(pht('Add Members')) 86 - ->setDatasource(new PhabricatorPeopleDatasource())) 87 - ->appendChild( 88 - id(new AphrontFormSubmitControl()) 89 - ->addCancelButton('/project/view/'.$project->getID().'/') 90 - ->setValue(pht('Add Members'))); 82 + $form_box = null; 83 + $title = pht('Add Members'); 84 + if ($can_edit) { 85 + $header_name = pht('Edit Members'); 86 + $view_uri = $this->getApplicationURI('profile/'.$project->getID().'/'); 91 87 92 - $member_list = $this->renderMemberList($project, $handles); 88 + $form = new AphrontFormView(); 89 + $form 90 + ->setUser($user) 91 + ->appendChild( 92 + id(new AphrontFormTokenizerControl()) 93 + ->setName('phids') 94 + ->setLabel(pht('Add Members')) 95 + ->setDatasource(new PhabricatorPeopleDatasource())) 96 + ->appendChild( 97 + id(new AphrontFormSubmitControl()) 98 + ->addCancelButton($view_uri) 99 + ->setValue(pht('Add Members'))); 100 + $form_box = id(new PHUIObjectBoxView()) 101 + ->setHeaderText($title) 102 + ->setForm($form); 103 + } 93 104 94 - $form_box = id(new PHUIObjectBoxView()) 95 - ->setHeaderText($title) 96 - ->setForm($form); 105 + $member_list = $this->renderMemberList($project, $handles); 97 106 98 - $crumbs = $this->buildApplicationCrumbs($this->buildSideNavView()) 99 - ->addTextCrumb( 100 - $project->getName(), 101 - '/project/view/'.$project->getID().'/') 102 - ->addTextCrumb(pht('Edit Members'), $this->getApplicationURI()); 107 + $nav = $this->buildIconNavView($project); 108 + $nav->selectFilter("members/{$id}/"); 109 + $nav->appendChild($form_box); 110 + $nav->appendChild($member_list); 103 111 104 112 return $this->buildApplicationPage( 105 113 array( 106 - $crumbs, 107 - $form_box, 108 - $member_list, 114 + $nav, 109 115 ), 110 116 array( 111 117 'title' => $title, ··· 119 125 $request = $this->getRequest(); 120 126 $viewer = $request->getUser(); 121 127 128 + $can_edit = PhabricatorPolicyFilter::hasCapability( 129 + $viewer, 130 + $project, 131 + PhabricatorPolicyCapability::CAN_EDIT); 132 + 122 133 $list = id(new PHUIObjectItemListView()) 123 - ->setNoDataString(pht('This project does not have any members.')); 134 + ->setNoDataString(pht('This project does not have any members.')) 135 + ->setStackable(true); 124 136 125 137 foreach ($handles as $handle) { 126 138 $remove_uri = $this->getApplicationURI( ··· 131 143 ->setHref($handle->getURI()) 132 144 ->setImageURI($handle->getImageURI()); 133 145 134 - $item->addAction( 135 - id(new PHUIListItemView()) 136 - ->setIcon('fa-times') 137 - ->setName(pht('Remove')) 138 - ->setHref($remove_uri) 139 - ->setWorkflow(true)); 146 + if ($can_edit) { 147 + $item->addAction( 148 + id(new PHUIListItemView()) 149 + ->setIcon('fa-times') 150 + ->setName(pht('Remove')) 151 + ->setHref($remove_uri) 152 + ->setWorkflow(true)); 153 + } 140 154 141 155 $list->addItem($item); 142 156 } 143 157 144 - return $list; 158 + $box = id(new PHUIObjectBoxView()) 159 + ->setHeaderText(pht('Members')) 160 + ->appendChild($list); 161 + 162 + return $box; 145 163 } 146 164 }
+27 -102
src/applications/project/controller/PhabricatorProjectProfileController.php
··· 3 3 final class PhabricatorProjectProfileController 4 4 extends PhabricatorProjectController { 5 5 6 - private $id; 7 - private $slug; 8 - 9 6 public function shouldAllowPublic() { 10 7 return true; 11 8 } 12 9 13 - public function willProcessRequest(array $data) { 14 - // via /project/view/$id/ 15 - $this->id = idx($data, 'id'); 16 - // via /tag/$slug/ 17 - $this->slug = idx($data, 'slug'); 18 - } 19 - 20 - public function processRequest() { 21 - $request = $this->getRequest(); 10 + public function handleRequest(AphrontRequest $request) { 22 11 $user = $request->getUser(); 23 12 24 13 $query = id(new PhabricatorProjectQuery()) ··· 27 16 ->needWatchers(true) 28 17 ->needImages(true) 29 18 ->needSlugs(true); 30 - if ($this->slug) { 31 - $query->withSlugs(array($this->slug)); 19 + $id = $request->getURIData('id'); 20 + $slug = $request->getURIData('slug'); 21 + if ($slug) { 22 + $query->withSlugs(array($slug)); 32 23 } else { 33 - $query->withIDs(array($this->id)); 24 + $query->withIDs(array($id)); 34 25 } 35 26 $project = $query->executeOne(); 36 27 if (!$project) { 37 28 return new Aphront404Response(); 38 29 } 39 - if ($this->slug && $this->slug != $project->getPrimarySlug()) { 30 + if ($slug && $slug != $project->getPrimarySlug()) { 40 31 return id(new AphrontRedirectResponse()) 41 32 ->setURI('/tag/'.$project->getPrimarySlug().'/'); 42 33 } 43 34 44 35 $picture = $project->getProfileImageURI(); 45 - 46 36 require_celerity_resource('phabricator-profile-css'); 47 - 48 37 $tasks = $this->renderTasksPage($project); 38 + $content = phutil_tag_div('phabricator-project-layout', $tasks); 49 39 50 - $query = new PhabricatorFeedQuery(); 51 - $query->setFilterPHIDs( 52 - array( 53 - $project->getPHID(), 54 - )); 55 - $query->setLimit(50); 56 - $query->setViewer($this->getRequest()->getUser()); 57 - $stories = $query->execute(); 58 - $feed = $this->renderStories($stories); 59 - 60 - $content = phutil_tag_div( 61 - 'phabricator-project-layout', 62 - array($tasks, $feed)); 63 - 64 - $id = $project->getID(); 65 - $icon = id(new PHUIIconView()) 66 - ->setIconFont('fa-columns'); 67 - $board_btn = id(new PHUIButtonView()) 68 - ->setTag('a') 69 - ->setText(pht('Workboard')) 70 - ->setHref($this->getApplicationURI("board/{$id}/")) 71 - ->setIcon($icon); 40 + $phid = $project->getPHID(); 41 + $create_uri = '/maniphest/task/create/?projects='.$phid; 42 + $icon_new = id(new PHUIIconView()) 43 + ->setIconFont('fa-plus'); 44 + $button_add = id(new PHUIButtonView()) 45 + ->setTag('a') 46 + ->setText(pht('New Task')) 47 + ->setHref($create_uri) 48 + ->setIcon($icon_new); 72 49 73 50 $header = id(new PHUIHeaderView()) 74 51 ->setHeader($project->getName()) 75 52 ->setUser($user) 76 53 ->setPolicyObject($project) 77 54 ->setImage($picture) 78 - ->addActionLink($board_btn); 55 + ->addActionLink($button_add); 79 56 80 57 if ($project->getStatus() == PhabricatorProjectStatus::STATUS_ACTIVE) { 81 58 $header->setStatus('fa-check', 'bluegrey', pht('Active')); ··· 86 63 $actions = $this->buildActionListView($project); 87 64 $properties = $this->buildPropertyListView($project, $actions); 88 65 89 - $crumbs = $this->buildApplicationCrumbs(); 90 - $crumbs->addTextCrumb($project->getName()); 91 - 92 66 $object_box = id(new PHUIObjectBoxView()) 93 67 ->setHeader($header) 94 68 ->addPropertyList($properties); 95 69 70 + $nav = $this->buildIconNavView($project); 71 + $nav->selectFilter("profile/{$id}/"); 72 + $nav->appendChild($object_box); 73 + $nav->appendChild($content); 74 + 96 75 return $this->buildApplicationPage( 97 76 array( 98 - $crumbs, 99 - $object_box, 100 - $content, 77 + $nav, 101 78 ), 102 79 array( 103 80 'title' => $project->getName(), 104 81 )); 105 82 } 106 83 107 - private function renderFeedPage(PhabricatorProject $project) { 108 - 109 - $query = new PhabricatorFeedQuery(); 110 - $query->setFilterPHIDs(array($project->getPHID())); 111 - $query->setViewer($this->getRequest()->getUser()); 112 - $query->setLimit(100); 113 - $stories = $query->execute(); 114 - 115 - if (!$stories) { 116 - return pht('There are no stories about this project.'); 117 - } 118 - 119 - return $this->renderStories($stories); 120 - } 121 - 122 - private function renderStories(array $stories) { 123 - assert_instances_of($stories, 'PhabricatorFeedStory'); 124 - 125 - $builder = new PhabricatorFeedBuilder($stories); 126 - $builder->setUser($this->getRequest()->getUser()); 127 - $builder->setShowHovercards(true); 128 - $view = $builder->buildView(); 129 - 130 - return phutil_tag_div( 131 - 'profile-feed', 132 - $view->render()); 133 - } 134 - 135 - 136 84 private function renderTasksPage(PhabricatorProject $project) { 137 85 138 86 $user = $this->getRequest()->getUser(); 139 - $limit = 10; 87 + $limit = 50; 140 88 141 89 $query = id(new ManiphestTaskQuery()) 142 90 ->setViewer($user) ··· 168 116 '/maniphest/?statuses=%s&allProjects=%s#R', 169 117 implode(',', ManiphestTaskStatus::getOpenStatusConstants()), 170 118 $phid); 171 - $create_uri = '/maniphest/task/create/?projects='.$phid; 172 119 $icon = id(new PHUIIconView()) 173 - ->setIconFont('fa-list'); 120 + ->setIconFont('fa-search'); 174 121 $button_view = id(new PHUIButtonView()) 175 122 ->setTag('a') 176 - ->setText(pht('View All')) 123 + ->setText(pht('View Query')) 177 124 ->setHref($view_uri) 178 125 ->setIcon($icon); 179 - $icon_new = id(new PHUIIconView()) 180 - ->setIconFont('fa-plus'); 181 - $button_add = id(new PHUIButtonView()) 182 - ->setTag('a') 183 - ->setText(pht('New Task')) 184 - ->setHref($create_uri) 185 - ->setIcon($icon_new); 186 126 187 127 $header = id(new PHUIHeaderView()) 188 - ->addActionLink($button_add) 189 128 ->addActionLink($button_view); 190 129 191 130 if ($count > $limit) { ··· 216 155 $viewer, 217 156 $project, 218 157 PhabricatorPolicyCapability::CAN_EDIT); 219 - 220 - $view->addAction( 221 - id(new PhabricatorActionView()) 222 - ->setName(pht('Edit Project')) 223 - ->setIcon('fa-pencil') 224 - ->setHref($this->getApplicationURI("edit/{$id}/"))); 225 - 226 - $view->addAction( 227 - id(new PhabricatorActionView()) 228 - ->setName(pht('Edit Members')) 229 - ->setIcon('fa-users') 230 - ->setHref($this->getApplicationURI("members/{$id}/")) 231 - ->setDisabled(!$can_edit) 232 - ->setWorkflow(!$can_edit)); 233 158 234 159 $action = null; 235 160 if (!$project->isUserMember($viewer->getPHID())) {
+1 -1
src/applications/project/controller/PhabricatorProjectUpdateController.php
··· 42 42 return new Aphront404Response(); 43 43 } 44 44 45 - $project_uri = '/project/view/'.$project->getID().'/'; 45 + $project_uri = $this->getApplicationURI('profile/'.$project->getID().'/'); 46 46 47 47 if ($process_action) { 48 48
+56
src/applications/project/controller/PhabricatorProjectViewController.php
··· 1 + <?php 2 + 3 + final class PhabricatorProjectViewController 4 + extends PhabricatorProjectController { 5 + 6 + public function shouldAllowPublic() { 7 + return true; 8 + } 9 + 10 + public function handleRequest(AphrontRequest $request) { 11 + $request = $this->getRequest(); 12 + $user = $request->getUser(); 13 + 14 + $query = id(new PhabricatorProjectQuery()) 15 + ->setViewer($user) 16 + ->needMembers(true) 17 + ->needWatchers(true) 18 + ->needImages(true) 19 + ->needSlugs(true); 20 + $id = $request->getURIData('id'); 21 + $slug = $request->getURIData('slug'); 22 + if ($slug) { 23 + $query->withSlugs(array($slug)); 24 + } else { 25 + $query->withIDs(array($id)); 26 + } 27 + $project = $query->executeOne(); 28 + if (!$project) { 29 + return new Aphront404Response(); 30 + } 31 + 32 + 33 + $columns = id(new PhabricatorProjectColumnQuery()) 34 + ->setViewer($user) 35 + ->withProjectPHIDs(array($project->getPHID())) 36 + ->execute(); 37 + if ($columns) { 38 + $controller = 'board'; 39 + } else { 40 + $controller = 'profile'; 41 + } 42 + 43 + switch ($controller) { 44 + case 'board': 45 + $controller_object = new PhabricatorProjectBoardViewController(); 46 + break; 47 + case 'profile': 48 + default: 49 + $controller_object = new PhabricatorProjectProfileController(); 50 + break; 51 + } 52 + 53 + return $this->delegateToController($controller_object); 54 + } 55 + 56 + }
+1 -1
src/applications/project/controller/PhabricatorProjectWatchController.php
··· 25 25 return new Aphront404Response(); 26 26 } 27 27 28 - $project_uri = '/project/view/'.$project->getID().'/'; 28 + $project_uri = $this->getApplicationURI('profile/'.$project->getID().'/'); 29 29 30 30 // You must be a member of a project to 31 31 if (!$project->isUserMember($viewer->getPHID())) {
+8
src/applications/project/query/PhabricatorProjectSearchEngine.php
··· 219 219 220 220 foreach ($projects as $key => $project) { 221 221 $id = $project->getID(); 222 + $profile_uri = $this->getApplicationURI("profile/{$id}/"); 222 223 $workboards_uri = $this->getApplicationURI("board/{$id}/"); 223 224 $members_uri = $this->getApplicationURI("members/{$id}/"); 225 + $profile_url = phutil_tag( 226 + 'a', 227 + array( 228 + 'href' => $profile_uri, 229 + ), 230 + pht('Profile')); 224 231 $workboards_url = phutil_tag( 225 232 'a', 226 233 array( ··· 252 259 ->setHref($this->getApplicationURI("view/{$id}/")) 253 260 ->setImageURI($project->getProfileImageURI()) 254 261 ->addAttribute($tag_list) 262 + ->addAttribute($profile_url) 255 263 ->addAttribute($workboards_url) 256 264 ->addAttribute($members_url); 257 265
+26
src/view/layout/AphrontSideNavFilterView.php
··· 27 27 private $crumbs; 28 28 private $classes = array(); 29 29 private $menuID; 30 + private $iconNav; 30 31 31 32 public function setMenuID($menu_id) { 32 33 $this->menuID = $menu_id; ··· 61 62 return $this->crumbs; 62 63 } 63 64 65 + public function setIconNav($nav) { 66 + $this->iconNav = $nav; 67 + return $this; 68 + } 69 + 64 70 public function setActive($active) { 65 71 $this->active = $active; 66 72 return $this; ··· 94 100 $key, $name, $uri, PHUIListItemView::TYPE_LINK); 95 101 } 96 102 103 + public function addIcon($key, $name, $icon, $image = null) { 104 + $href = clone $this->baseURI; 105 + $href->setPath(rtrim($href->getPath().$key, '/').'/'); 106 + $href = (string)$href; 107 + 108 + $item = id(new PHUIListItemView()) 109 + ->setKey($key) 110 + ->setRenderNameAsTooltip(true) 111 + ->setType(PHUIListItemView::TYPE_ICON_NAV) 112 + ->setIcon($icon) 113 + ->setHref($href) 114 + ->setName($name) 115 + ->setProfileImage($image); 116 + return $this->addMenuItem($item); 117 + } 118 + 97 119 public function addButton($key, $name, $uri = null) { 98 120 return $this->addThing( 99 121 $key, $name, $uri, PHUIListItemView::TYPE_BUTTON); ··· 108 130 $item = id(new PHUIListItemView()) 109 131 ->setName($name) 110 132 ->setType($type); 133 + 111 134 112 135 if (strlen($key)) { 113 136 $item->setKey($key); ··· 192 215 193 216 $nav_classes = array(); 194 217 $nav_classes[] = 'phabricator-nav'; 218 + if ($this->iconNav) { 219 + $nav_classes[] = 'phabricator-icon-nav'; 220 + } 195 221 196 222 $nav_id = null; 197 223 $drag_id = null;
+15
src/view/phui/PHUIListItemView.php
··· 9 9 const TYPE_CUSTOM = 'type-custom'; 10 10 const TYPE_DIVIDER = 'type-divider'; 11 11 const TYPE_ICON = 'type-icon'; 12 + const TYPE_ICON_NAV = 'type-icon-nav'; 12 13 13 14 const STATUS_WARN = 'phui-list-item-warn'; 14 15 const STATUS_FAIL = 'phui-list-item-fail'; ··· 26 27 private $statusColor; 27 28 private $order; 28 29 private $aural; 30 + private $profileImage; 29 31 30 32 public function setAural($aural) { 31 33 $this->aural = $aural; ··· 70 72 71 73 public function setAppIcon($icon) { 72 74 $this->appIcon = $icon; 75 + return $this; 76 + } 77 + 78 + public function setProfileImage($image) { 79 + $this->profileImage = $image; 73 80 return $this; 74 81 } 75 82 ··· 170 177 171 178 if ($this->name) { 172 179 if ($this->getRenderNameAsTooltip()) { 180 + Javelin::initBehavior('phabricator-tooltips'); 173 181 $sigil = 'has-tooltip'; 174 182 $meta = array( 175 183 'tip' => $this->name, 184 + 'align' => 'E', 176 185 ); 177 186 } else { 178 187 $external = null; ··· 222 231 $icon = id(new PHUIIconView()) 223 232 ->addClass('phui-list-item-icon') 224 233 ->setIconFont($icon_name); 234 + } 235 + 236 + if ($this->profileImage) { 237 + $icon = id(new PHUIIconView()) 238 + ->setHeadSize(PHUIIconView::HEAD_SMALL) 239 + ->setImage($this->profileImage); 225 240 } 226 241 227 242 if ($this->appIcon) {
+8 -8
webroot/rsrc/css/aphront/multi-column.css
··· 159 159 display: block; 160 160 width: auto; 161 161 } 162 - .device-desktop .aphront-multi-column-column-outer { 162 + .device-desktop .dashboard-view .aphront-multi-column-column-outer { 163 163 display: block; 164 164 border: none; 165 165 } 166 - .device-desktop .aphront-multi-column-column.mlr { 166 + .device-desktop .dashboard-view .aphront-multi-column-column.mlr { 167 167 margin: 0; 168 168 } 169 - .device-desktop .aphront-multi-column-fluid .aphront-multi-column-2-up 170 - .aphront-multi-column-column-outer.half { 169 + .device-desktop .dashboard-view .aphront-multi-column-fluid 170 + .aphront-multi-column-2-up .aphront-multi-column-column-outer.half { 171 171 width: auto; 172 172 margin: 0 0 16px; 173 173 } 174 - .device-desktop .aphront-multi-column-fluid .aphront-multi-column-2-up 175 - .aphront-multi-column-column-outer.thirds { 174 + .device-desktop .dashboard-view .aphront-multi-column-fluid 175 + .aphront-multi-column-2-up .aphront-multi-column-column-outer.thirds { 176 176 width: auto; 177 177 margin: 0 0 16px; 178 178 } 179 - .device-desktop .aphront-multi-column-fluid .aphront-multi-column-2-up 180 - .aphront-multi-column-column-outer.third { 179 + .device-desktop .dashboard-view .aphront-multi-column-fluid 180 + .aphront-multi-column-2-up .aphront-multi-column-column-outer.third { 181 181 width: auto; 182 182 margin: 0 0 16px; 183 183 }
+10
webroot/rsrc/css/application/profile/profile-view.css
··· 51 51 .device-tablet .phabricator-project-layout .profile-feed { 52 52 padding: 16px; 53 53 } 54 + 55 + .phabricator-project-feed { 56 + padding: 4px 0 12px 12px; 57 + max-width: 640px; 58 + } 59 + 60 + .device-phone .phabricator-project-feed { 61 + padding: 0 12px; 62 + width: auto; 63 + }
+41
webroot/rsrc/css/layout/phabricator-side-menu-view.css
··· 43 43 text-decoration: none; 44 44 background-color: {$hovergrey}; 45 45 } 46 + 47 + .device-desktop .phabricator-icon-nav .phabricator-nav-column-background, 48 + .device-desktop .phabricator-icon-nav .phabricator-nav-local { 49 + width: 40px; 50 + } 51 + 52 + .device-desktop .phabricator-icon-nav .phabricator-nav-content { 53 + margin-left: 41px; 54 + } 55 + 56 + .phabricator-icon-nav .phabricator-side-menu .phui-list-item-href { 57 + height: 40px; 58 + width: 40px; 59 + padding: 0; 60 + } 61 + 62 + .phabricator-icon-nav .phabricator-side-menu .phui-list-item-icon { 63 + font-size: 20px; 64 + width: 40px; 65 + line-height: 40px; 66 + text-align: center; 67 + vertical-align: bottom; 68 + } 69 + 70 + .phabricator-icon-nav .phabricator-side-menu .phui-list-item-selected { 71 + border: none; 72 + } 73 + 74 + .phabricator-icon-nav .phabricator-side-menu .phui-list-item-selected 75 + .phui-icon-view { 76 + color: {$sky}; 77 + } 78 + 79 + .phabricator-icon-nav .phui-icon-view.phuihead-small { 80 + height: 24px; 81 + width: 24px; 82 + border: 1px solid #fff; 83 + background-size: 24px; 84 + display: inline-block; 85 + margin: 7px; 86 + }
+2 -2
webroot/rsrc/css/phui/phui-object-item-list-view.css
··· 19 19 } 20 20 21 21 .phui-object-box .phui-object-item-list-view.phui-object-list-flush { 22 - padding: 8px 12px 4px 12px; 22 + padding: 8px 8px 4px 8px; 23 23 background-color: #E5E8EE; 24 24 } 25 25 ··· 38 38 border-color: {$lightgreyborder}; 39 39 margin: 5px 0; 40 40 overflow: hidden; 41 - border-left-width: 6px; 41 + border-left-width: 4px; 42 42 background: #fff; 43 43 margin-bottom: 4px; 44 44 }
+9
webroot/rsrc/css/phui/phui-workboard-view.css
··· 73 73 margin: 0 3px; 74 74 } 75 75 76 + .device-desktop .project-board-wrapper .phui-workboard-view-shadow { 77 + left: 53px; 78 + } 79 + 80 + .device-desktop .phui-workboard-view .aphront-multi-column-fixed 81 + .aphront-multi-column-inner { 82 + margin-left: 0; 83 + } 84 + 76 85 .device-tablet .project-board-wrapper { 77 86 margin-left: 8px; 78 87 margin-right: 8px;