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

New 'default' homepage

Summary: Ref T11132. This is a new default default (no dashboard) homepage. It offers (Diffs) (Tasks) (Repositories) in the main column and (Feed) in the side column. No NUX stuff, No logged out public view (upcoming diff). This should be complete, but unclear how to bucketize Differential.

Test Plan: Test new account's default homepage.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Maniphest Tasks: T11132

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

+119 -305
-6
src/applications/differential/view/DifferentialRevisionListView.php
··· 7 7 8 8 private $revisions; 9 9 private $handles; 10 - private $highlightAge; 11 10 private $header; 12 11 private $noDataString; 13 12 private $noBox; ··· 36 35 public function setRevisions(array $revisions) { 37 36 assert_instances_of($revisions, 'DifferentialRevision'); 38 37 $this->revisions = $revisions; 39 - return $this; 40 - } 41 - 42 - public function setHighlightAge($bool) { 43 - $this->highlightAge = $bool; 44 38 return $this; 45 39 } 46 40
+117 -298
src/applications/home/controller/PhabricatorHomeMainController.php
··· 2 2 3 3 final class PhabricatorHomeMainController extends PhabricatorHomeController { 4 4 5 - private $minipanels = array(); 6 - 7 5 public function shouldAllowPublic() { 8 6 return true; 9 7 } ··· 13 11 } 14 12 15 13 public function handleRequest(AphrontRequest $request) { 16 - $user = $request->getUser(); 14 + $viewer = $request->getViewer(); 17 15 18 16 $dashboard = PhabricatorDashboardInstall::getDashboard( 19 - $user, 20 - $user->getPHID(), 17 + $viewer, 18 + $viewer->getPHID(), 21 19 get_class($this->getCurrentApplication())); 22 20 23 21 if (!$dashboard) { 24 22 $dashboard = PhabricatorDashboardInstall::getDashboard( 25 - $user, 23 + $viewer, 26 24 PhabricatorHomeApplication::DASHBOARD_DEFAULT, 27 25 get_class($this->getCurrentApplication())); 28 26 } 29 27 30 28 if ($dashboard) { 31 29 $content = id(new PhabricatorDashboardRenderingEngine()) 32 - ->setViewer($user) 30 + ->setViewer($viewer) 33 31 ->setDashboard($dashboard) 34 32 ->renderDashboard(); 35 33 } else { 36 - $project_query = new PhabricatorProjectQuery(); 37 - $project_query->setViewer($user); 38 - $project_query->withMemberPHIDs(array($user->getPHID())); 39 - $projects = $project_query->execute(); 40 - 41 - $content = $this->buildMainResponse($projects); 34 + $content = $this->buildMainResponse(); 42 35 } 43 36 44 37 if (!$request->getURIData('only')) { ··· 46 39 $nav->appendChild( 47 40 array( 48 41 $content, 49 - id(new PhabricatorGlobalUploadTargetView())->setUser($user), 42 + id(new PhabricatorGlobalUploadTargetView())->setUser($viewer), 50 43 )); 51 44 $content = $nav; 52 45 } ··· 58 51 59 52 } 60 53 61 - private function buildMainResponse(array $projects) { 62 - assert_instances_of($projects, 'PhabricatorProject'); 63 - $viewer = $this->getRequest()->getUser(); 54 + private function buildMainResponse() { 55 + require_celerity_resource('phabricator-dashboard-css'); 56 + $viewer = $this->getViewer(); 64 57 65 58 $has_maniphest = PhabricatorApplication::isClassInstalledForViewer( 66 59 'PhabricatorManiphestApplication', 67 60 $viewer); 68 61 69 - $has_audit = PhabricatorApplication::isClassInstalledForViewer( 70 - 'PhabricatorAuditApplication', 62 + $has_diffusion = PhabricatorApplication::isClassInstalledForViewer( 63 + 'PhabricatorDiffusionApplication', 71 64 $viewer); 72 65 73 66 $has_differential = PhabricatorApplication::isClassInstalledForViewer( 74 67 'PhabricatorDifferentialApplication', 75 68 $viewer); 76 69 70 + $revision_panel = null; 71 + if ($has_differential) { 72 + $revision_panel = $this->buildRevisionPanel(); 73 + } 74 + 75 + $tasks_panel = null; 77 76 if ($has_maniphest) { 78 - $unbreak_panel = $this->buildUnbreakNowPanel(); 79 - $triage_panel = $this->buildNeedsTriagePanel($projects); 80 77 $tasks_panel = $this->buildTasksPanel(); 81 - } else { 82 - $unbreak_panel = null; 83 - $triage_panel = null; 84 - $tasks_panel = null; 85 78 } 86 79 87 - if ($has_audit) { 88 - $audit_panel = $this->buildAuditPanel(); 89 - $commit_panel = $this->buildCommitPanel(); 90 - } else { 91 - $audit_panel = null; 92 - $commit_panel = null; 80 + $repository_panel = null; 81 + if ($has_diffusion) { 82 + $repository_panel = $this->buildRepositoryPanel(); 93 83 } 94 84 95 - if (PhabricatorEnv::getEnvConfig('welcome.html') !== null) { 96 - $welcome_panel = $this->buildWelcomePanel(); 97 - } else { 98 - $welcome_panel = null; 99 - } 85 + $feed_panel = $this->buildFeedPanel(); 100 86 101 - if ($has_differential) { 102 - $revision_panel = $this->buildRevisionPanel(); 103 - } else { 104 - $revision_panel = null; 105 - } 87 + $dashboard = id(new AphrontMultiColumnView()) 88 + ->setFluidlayout(true) 89 + ->setGutter(AphrontMultiColumnView::GUTTER_LARGE); 106 90 107 - $home = phutil_tag( 91 + $main_panel = phutil_tag( 108 92 'div', 109 93 array( 110 94 'class' => 'homepage-panel', 111 95 ), 112 96 array( 113 - $welcome_panel, 114 - $unbreak_panel, 115 - $triage_panel, 116 97 $revision_panel, 117 98 $tasks_panel, 118 - $audit_panel, 119 - $commit_panel, 120 - $this->minipanels, 99 + $repository_panel, 121 100 )); 122 - return $home; 123 - } 124 - 125 - private function buildUnbreakNowPanel() { 126 - $unbreak_now = PhabricatorEnv::getEnvConfig( 127 - 'maniphest.priorities.unbreak-now'); 128 - if (!$unbreak_now) { 129 - return null; 130 - } 131 - 132 - $user = $this->getRequest()->getUser(); 133 - 134 - $task_query = id(new ManiphestTaskQuery()) 135 - ->setViewer($user) 136 - ->withStatuses(ManiphestTaskStatus::getOpenStatusConstants()) 137 - ->withPriorities(array($unbreak_now)) 138 - ->needProjectPHIDs(true) 139 - ->setLimit(10); 101 + $dashboard->addColumn($main_panel, 'thirds'); 140 102 141 - $tasks = $task_query->execute(); 142 - 143 - if (!$tasks) { 144 - return $this->renderMiniPanel( 145 - pht('No "Unbreak Now!" Tasks'), 146 - pht('Nothing appears to be critically broken right now.')); 147 - } 103 + $side_panel = phutil_tag( 104 + 'div', 105 + array( 106 + 'class' => 'homepage-side-panel', 107 + ), 108 + array( 109 + $feed_panel, 110 + )); 111 + $dashboard->addColumn($side_panel, 'third'); 148 112 149 - $href = urisprintf( 150 - '/maniphest/?statuses=open()&priorities=%s#R', 151 - $unbreak_now); 152 - $title = pht('Unbreak Now!'); 153 - $panel = new PHUIObjectBoxView(); 154 - $panel->setHeader($this->renderSectionHeader($title, $href)); 155 - $panel->setObjectList($this->buildTaskListView($tasks)); 113 + $view = id(new PHUIBoxView()) 114 + ->addClass('dashboard-view') 115 + ->appendChild($dashboard); 156 116 157 - return $panel; 117 + return $view; 158 118 } 159 119 160 - private function buildNeedsTriagePanel(array $projects) { 161 - assert_instances_of($projects, 'PhabricatorProject'); 120 + private function buildHomepagePanel($title, $href, $view) { 121 + $title = phutil_tag( 122 + 'a', 123 + array( 124 + 'href' => $href, 125 + ), 126 + $title); 162 127 163 - $needs_triage = PhabricatorEnv::getEnvConfig( 164 - 'maniphest.priorities.needs-triage'); 165 - if (!$needs_triage) { 166 - return null; 167 - } 128 + $icon = id(new PHUIIconView()) 129 + ->setIcon('fa-search') 130 + ->setHref($href); 168 131 169 - $user = $this->getRequest()->getUser(); 170 - if (!$user->isLoggedIn()) { 171 - return null; 172 - } 132 + $header = id(new PHUIHeaderView()) 133 + ->setHeader($title) 134 + ->addActionItem($icon); 173 135 174 - if ($projects) { 175 - $task_query = id(new ManiphestTaskQuery()) 176 - ->setViewer($user) 177 - ->withStatuses(ManiphestTaskStatus::getOpenStatusConstants()) 178 - ->withPriorities(array($needs_triage)) 179 - ->withEdgeLogicPHIDs( 180 - PhabricatorProjectObjectHasProjectEdgeType::EDGECONST, 181 - PhabricatorQueryConstraint::OPERATOR_OR, 182 - mpull($projects, 'getPHID')) 183 - ->needProjectPHIDs(true) 184 - ->setLimit(10); 185 - $tasks = $task_query->execute(); 186 - } else { 187 - $tasks = array(); 188 - } 136 + $box = id(new PHUIObjectBoxView()) 137 + ->setHeader($header); 189 138 190 - if (!$tasks) { 191 - return $this->renderMiniPanel( 192 - pht('No "Needs Triage" Tasks'), 193 - pht('No tasks tagged with projects you are a member of need triage.')); 139 + if ($view->getObjectList()) { 140 + $box->setObjectList($view->getObjectList()); 141 + } 142 + if ($view->getContent()) { 143 + $box->appendChild($view->getContent()); 194 144 } 195 145 196 - $title = pht('Needs Triage'); 197 - $href = urisprintf( 198 - '/maniphest/?statuses=open()&priorities=%s&projects=projects(%s)#R', 199 - $needs_triage, 200 - $user->getPHID()); 201 - $panel = new PHUIObjectBoxView(); 202 - $panel->setHeader($this->renderSectionHeader($title, $href)); 203 - $panel->setObjectList($this->buildTaskListView($tasks)); 204 - 205 - return $panel; 146 + return $box; 206 147 } 207 148 208 149 private function buildRevisionPanel() { 209 150 $viewer = $this->getViewer(); 210 - 211 - $revisions = PhabricatorDifferentialApplication::loadNeedAttentionRevisions( 212 - $viewer); 213 - 214 - if (!$revisions) { 215 - return $this->renderMiniPanel( 216 - pht('No Waiting Revisions'), 217 - pht('No revisions are waiting on you.')); 151 + if (!$viewer->isLoggedIn()) { 152 + return null; 218 153 } 219 154 220 - $title = pht('Revisions Waiting on You'); 221 - $href = '/differential/'; 222 - $panel = new PHUIObjectBoxView(); 223 - $panel->setHeader($this->renderSectionHeader($title, $href)); 155 + $engine = new DifferentialRevisionSearchEngine(); 156 + $engine->setViewer($viewer); 157 + $saved = $engine->buildSavedQueryFromBuiltin('active'); 158 + $query = $engine->buildQueryFromSavedQuery($saved); 159 + $pager = $engine->newPagerForSavedQuery($saved); 160 + $pager->setPageSize(15); 161 + $results = $engine->executeQuery($query, $pager); 162 + $view = $engine->renderResults($results, $saved); 224 163 225 - $revision_view = id(new DifferentialRevisionListView()) 226 - ->setHighlightAge(true) 227 - ->setRevisions($revisions) 228 - ->setUser($viewer); 164 + $title = pht('Active Revisions'); 165 + $href = '/differential/query/active/'; 229 166 230 - $phids = array_merge( 231 - array($viewer->getPHID()), 232 - $revision_view->getRequiredHandlePHIDs()); 233 - $handles = $this->loadViewerHandles($phids); 234 - 235 - $revision_view->setHandles($handles); 236 - 237 - $list_view = $revision_view->render(); 238 - 239 - $panel->setObjectList($list_view); 240 - 241 - return $panel; 242 - } 243 - 244 - private function buildWelcomePanel() { 245 - $panel = new PHUIObjectBoxView(); 246 - $panel->setHeaderText(pht('Welcome')); 247 - $panel->appendChild( 248 - phutil_safe_html( 249 - PhabricatorEnv::getEnvConfig('welcome.html'))); 250 - 251 - return $panel; 167 + return $this->buildHomepagePanel($title, $href, $view); 252 168 } 253 169 254 170 private function buildTasksPanel() { 255 - $user = $this->getRequest()->getUser(); 256 - $user_phid = $user->getPHID(); 257 - 258 - $task_query = id(new ManiphestTaskQuery()) 259 - ->setViewer($user) 260 - ->withStatuses(ManiphestTaskStatus::getOpenStatusConstants()) 261 - ->setGroupBy(ManiphestTaskQuery::GROUP_PRIORITY) 262 - ->withOwners(array($user_phid)) 263 - ->needProjectPHIDs(true) 264 - ->setLimit(10); 265 - 266 - $tasks = $task_query->execute(); 267 - 171 + $viewer = $this->getViewer(); 268 172 269 - if (!$tasks) { 270 - return $this->renderMiniPanel( 271 - pht('No Assigned Tasks'), 272 - pht('You have no assigned tasks.')); 273 - } 274 - 173 + $query = 'assigned'; 275 174 $title = pht('Assigned Tasks'); 276 175 $href = '/maniphest/query/assigned/'; 277 - $panel = new PHUIObjectBoxView(); 278 - $panel->setHeader($this->renderSectionHeader($title, $href)); 279 - $panel->setObjectList($this->buildTaskListView($tasks)); 280 - 281 - return $panel; 282 - } 283 - 284 - private function buildTaskListView(array $tasks) { 285 - assert_instances_of($tasks, 'ManiphestTask'); 286 - $user = $this->getRequest()->getUser(); 287 - 288 - $phids = array_merge( 289 - array_filter(mpull($tasks, 'getOwnerPHID')), 290 - array_mergev(mpull($tasks, 'getProjectPHIDs'))); 291 - 292 - $handles = $this->loadViewerHandles($phids); 176 + if (!$viewer->isLoggedIn()) { 177 + $query = 'open'; 178 + $title = pht('Open Tasks'); 179 + $href = '/maniphest/query/open/'; 180 + } 293 181 294 - $view = new ManiphestTaskListView(); 295 - $view->setTasks($tasks); 296 - $view->setUser($user); 297 - $view->setHandles($handles); 182 + $engine = new ManiphestTaskSearchEngine(); 183 + $engine->setViewer($viewer); 184 + $saved = $engine->buildSavedQueryFromBuiltin($query); 185 + $query = $engine->buildQueryFromSavedQuery($saved); 186 + $pager = $engine->newPagerForSavedQuery($saved); 187 + $pager->setPageSize(15); 188 + $results = $engine->executeQuery($query, $pager); 189 + $view = $engine->renderResults($results, $saved); 298 190 299 - return $view; 191 + return $this->buildHomepagePanel($title, $href, $view); 300 192 } 301 193 302 - private function renderSectionHeader($title, $href) { 303 - $title = phutil_tag( 304 - 'a', 305 - array( 306 - 'href' => $href, 307 - ), 308 - $title); 309 - $icon = id(new PHUIIconView()) 310 - ->setIcon('fa-search') 311 - ->setHref($href); 312 - $header = id(new PHUIHeaderView()) 313 - ->setHeader($title) 314 - ->addActionItem($icon); 315 - return $header; 316 - } 194 + public function buildFeedPanel() { 195 + $viewer = $this->getViewer(); 317 196 318 - private function renderMiniPanel($title, $body) { 319 - $panel = new PHUIInfoView(); 320 - $panel->setSeverity(PHUIInfoView::SEVERITY_NODATA); 321 - $panel->appendChild( 322 - phutil_tag( 323 - 'p', 324 - array( 325 - ), 326 - array( 327 - phutil_tag('strong', array(), $title.': '), 328 - $body, 329 - ))); 330 - $this->minipanels[] = $panel; 331 - } 332 - 333 - public function buildAuditPanel() { 334 - $request = $this->getRequest(); 335 - $user = $request->getUser(); 336 - 337 - $phids = PhabricatorAuditCommentEditor::loadAuditPHIDsForUser($user); 338 - 339 - $query = id(new DiffusionCommitQuery()) 340 - ->setViewer($user) 341 - ->withNeedsAuditByPHIDs($phids) 342 - ->withAuditStatus(DiffusionCommitQuery::AUDIT_STATUS_OPEN) 343 - ->needAuditRequests(true) 344 - ->needCommitData(true) 345 - ->setLimit(10); 346 - 347 - $commits = $query->execute(); 348 - 349 - if (!$commits) { 350 - return $this->renderMinipanel( 351 - pht('No Audits'), 352 - pht('No commits are waiting for you to audit them.')); 353 - } 354 - 355 - $view = id(new PhabricatorAuditListView()) 356 - ->setCommits($commits) 357 - ->setUser($user); 197 + $engine = new PhabricatorFeedSearchEngine(); 198 + $engine->setViewer($viewer); 199 + $saved = $engine->buildSavedQueryFromBuiltin('all'); 200 + $query = $engine->buildQueryFromSavedQuery($saved); 201 + $pager = $engine->newPagerForSavedQuery($saved); 202 + $pager->setPageSize(40); 203 + $results = $engine->executeQuery($query, $pager); 204 + $view = $engine->renderResults($results, $saved); 358 205 359 - $phids = $view->getRequiredHandlePHIDs(); 360 - $handles = $this->loadViewerHandles($phids); 361 - $view->setHandles($handles); 206 + $title = pht('Recent Activity'); 207 + $href = '/feed/'; 362 208 363 - $title = pht('Audits'); 364 - $href = '/audit/'; 365 - $panel = new PHUIObjectBoxView(); 366 - $panel->setHeader($this->renderSectionHeader($title, $href)); 367 - $panel->setObjectList($view); 368 - 369 - return $panel; 209 + return $this->buildHomepagePanel($title, $href, $view); 370 210 } 371 211 372 - public function buildCommitPanel() { 373 - $request = $this->getRequest(); 374 - $user = $request->getUser(); 212 + public function buildRepositoryPanel() { 213 + $viewer = $this->getViewer(); 375 214 376 - $phids = array($user->getPHID()); 215 + $engine = new PhabricatorRepositorySearchEngine(); 216 + $engine->setViewer($viewer); 217 + $saved = $engine->buildSavedQueryFromBuiltin('active'); 218 + $query = $engine->buildQueryFromSavedQuery($saved); 219 + $pager = $engine->newPagerForSavedQuery($saved); 220 + $pager->setPageSize(5); 221 + $results = $engine->executeQuery($query, $pager); 222 + $view = $engine->renderResults($results, $saved); 377 223 378 - $query = id(new DiffusionCommitQuery()) 379 - ->setViewer($user) 380 - ->withAuthorPHIDs($phids) 381 - ->withAuditStatus(DiffusionCommitQuery::AUDIT_STATUS_CONCERN) 382 - ->needCommitData(true) 383 - ->needAuditRequests(true) 384 - ->setLimit(10); 224 + $title = pht('Active Repositories'); 225 + $href = '/diffusion/'; 385 226 386 - $commits = $query->execute(); 387 - 388 - if (!$commits) { 389 - return $this->renderMinipanel( 390 - pht('No Problem Commits'), 391 - pht('No one has raised concerns with your commits.')); 392 - } 393 - 394 - $view = id(new PhabricatorAuditListView()) 395 - ->setCommits($commits) 396 - ->setUser($user); 397 - 398 - $phids = $view->getRequiredHandlePHIDs(); 399 - $handles = $this->loadViewerHandles($phids); 400 - $view->setHandles($handles); 401 - 402 - $title = pht('Problem Commits'); 403 - $href = '/audit/'; 404 - $panel = new PHUIObjectBoxView(); 405 - $panel->setHeader($this->renderSectionHeader($title, $href)); 406 - $panel->setObjectList($view); 407 - 408 - return $panel; 227 + return $this->buildHomepagePanel($title, $href, $view); 409 228 } 410 229 411 230 }
+2 -1
src/applications/maniphest/view/ManiphestTaskResultListView.php
··· 41 41 // If we didn't match anything, just pick up the default empty state. 42 42 if (!$tasks) { 43 43 return id(new PHUIObjectItemListView()) 44 - ->setUser($viewer); 44 + ->setUser($viewer) 45 + ->setNoDataString(pht('No tasks found.')); 45 46 } 46 47 47 48 $group_parameter = nonempty($query->getParameter('group'), 'priority');