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

Touch up basic usability of Dashboards

Summary: Ref T10390. This mostly shuffles layout into "View" and keepts "Manage" around for Edit/Copy/History. This feels better to me overall. Also tweaked some spacing and color.

Test Plan:
New Dashboard, edit Dashboard, shuffle panels. Create new panels.

{F2684043}

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Maniphest Tasks: T10390

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

+326 -200
+5 -5
resources/celerity/map.php
··· 9 9 'names' => array( 10 10 'conpherence.pkg.css' => 'a520d619', 11 11 'conpherence.pkg.js' => '6249a1cf', 12 - 'core.pkg.css' => '72ab63ef', 12 + 'core.pkg.css' => '2a5c3505', 13 13 'core.pkg.js' => '1fa7c0c5', 14 14 'darkconsole.pkg.js' => 'e7393ebb', 15 15 'differential.pkg.css' => '4815647b', ··· 55 55 'rsrc/css/application/contentsource/content-source-view.css' => '4b8b05d4', 56 56 'rsrc/css/application/countdown/timer.css' => '16c52f5c', 57 57 'rsrc/css/application/daemon/bulk-job.css' => 'df9c1d4a', 58 - 'rsrc/css/application/dashboard/dashboard.css' => '226c4dc6', 58 + 'rsrc/css/application/dashboard/dashboard.css' => '005e064e', 59 59 'rsrc/css/application/diff/inline-comment-summary.css' => '51efda3a', 60 60 'rsrc/css/application/differential/add-comment.css' => 'c47f8c40', 61 61 'rsrc/css/application/differential/changeset-view.css' => '6a9bdf9c', ··· 102 102 'rsrc/css/application/releeph/releeph-preview-branch.css' => 'b7a6f4a5', 103 103 'rsrc/css/application/releeph/releeph-request-differential-create-dialog.css' => '8d8b92cd', 104 104 'rsrc/css/application/releeph/releeph-request-typeahead.css' => '667a48ae', 105 - 'rsrc/css/application/search/application-search-view.css' => '20ae9d85', 105 + 'rsrc/css/application/search/application-search-view.css' => '66ee5d46', 106 106 'rsrc/css/application/search/search-results.css' => '64ad079a', 107 107 'rsrc/css/application/slowvote/slowvote.css' => 'a94b7230', 108 108 'rsrc/css/application/tokens/tokens.css' => '3d0f239e', ··· 556 556 'aphront-tokenizer-control-css' => '9a8cb501', 557 557 'aphront-tooltip-css' => '173b9431', 558 558 'aphront-typeahead-control-css' => 'd4f16145', 559 - 'application-search-view-css' => '20ae9d85', 559 + 'application-search-view-css' => '66ee5d46', 560 560 'auth-css' => '0877ed6e', 561 561 'bulk-job-css' => 'df9c1d4a', 562 562 'changeset-view-manager' => 'a2828756', ··· 786 786 'phabricator-content-source-view-css' => '4b8b05d4', 787 787 'phabricator-core-css' => '9f4cb463', 788 788 'phabricator-countdown-css' => '16c52f5c', 789 - 'phabricator-dashboard-css' => '226c4dc6', 789 + 'phabricator-dashboard-css' => '005e064e', 790 790 'phabricator-drag-and-drop-file-upload' => '58dea2fa', 791 791 'phabricator-draggable-list' => 'bea6e7f4', 792 792 'phabricator-fatal-config-template-css' => '8f18fa41',
+6 -2
src/__phutil_library_map__.php
··· 2464 2464 'PhabricatorDashboardAddPanelController' => 'applications/dashboard/controller/PhabricatorDashboardAddPanelController.php', 2465 2465 'PhabricatorDashboardApplication' => 'applications/dashboard/application/PhabricatorDashboardApplication.php', 2466 2466 'PhabricatorDashboardArchiveController' => 'applications/dashboard/controller/PhabricatorDashboardArchiveController.php', 2467 + 'PhabricatorDashboardArrangeController' => 'applications/dashboard/controller/PhabricatorDashboardArrangeController.php', 2467 2468 'PhabricatorDashboardController' => 'applications/dashboard/controller/PhabricatorDashboardController.php', 2468 2469 'PhabricatorDashboardCopyController' => 'applications/dashboard/controller/PhabricatorDashboardCopyController.php', 2469 2470 'PhabricatorDashboardDAO' => 'applications/dashboard/storage/PhabricatorDashboardDAO.php', ··· 2503 2504 'PhabricatorDashboardPanelTransactionQuery' => 'applications/dashboard/query/PhabricatorDashboardPanelTransactionQuery.php', 2504 2505 'PhabricatorDashboardPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelType.php', 2505 2506 'PhabricatorDashboardPanelViewController' => 'applications/dashboard/controller/PhabricatorDashboardPanelViewController.php', 2507 + 'PhabricatorDashboardProfileController' => 'applications/dashboard/controller/PhabricatorDashboardProfileController.php', 2506 2508 'PhabricatorDashboardProfileMenuItem' => 'applications/search/menuitem/PhabricatorDashboardProfileMenuItem.php', 2507 2509 'PhabricatorDashboardQuery' => 'applications/dashboard/query/PhabricatorDashboardQuery.php', 2508 2510 'PhabricatorDashboardQueryPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardQueryPanelType.php', ··· 7471 7473 'PhabricatorDashboardAddPanelController' => 'PhabricatorDashboardController', 7472 7474 'PhabricatorDashboardApplication' => 'PhabricatorApplication', 7473 7475 'PhabricatorDashboardArchiveController' => 'PhabricatorDashboardController', 7476 + 'PhabricatorDashboardArrangeController' => 'PhabricatorDashboardProfileController', 7474 7477 'PhabricatorDashboardController' => 'PhabricatorController', 7475 7478 'PhabricatorDashboardCopyController' => 'PhabricatorDashboardController', 7476 7479 'PhabricatorDashboardDAO' => 'PhabricatorLiskDAO', ··· 7482 7485 'PhabricatorDashboardInstall' => 'PhabricatorDashboardDAO', 7483 7486 'PhabricatorDashboardLayoutConfig' => 'Phobject', 7484 7487 'PhabricatorDashboardListController' => 'PhabricatorDashboardController', 7485 - 'PhabricatorDashboardManageController' => 'PhabricatorDashboardController', 7488 + 'PhabricatorDashboardManageController' => 'PhabricatorDashboardProfileController', 7486 7489 'PhabricatorDashboardMovePanelController' => 'PhabricatorDashboardController', 7487 7490 'PhabricatorDashboardNgrams' => 'PhabricatorSearchNgrams', 7488 7491 'PhabricatorDashboardPanel' => array( ··· 7521 7524 'PhabricatorDashboardPanelTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 7522 7525 'PhabricatorDashboardPanelType' => 'Phobject', 7523 7526 'PhabricatorDashboardPanelViewController' => 'PhabricatorDashboardController', 7527 + 'PhabricatorDashboardProfileController' => 'PhabricatorController', 7524 7528 'PhabricatorDashboardProfileMenuItem' => 'PhabricatorProfileMenuItem', 7525 7529 'PhabricatorDashboardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 7526 7530 'PhabricatorDashboardQueryPanelType' => 'PhabricatorDashboardPanelType', ··· 7535 7539 'PhabricatorDashboardTransactionEditor' => 'PhabricatorApplicationTransactionEditor', 7536 7540 'PhabricatorDashboardTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 7537 7541 'PhabricatorDashboardUninstallController' => 'PhabricatorDashboardController', 7538 - 'PhabricatorDashboardViewController' => 'PhabricatorDashboardController', 7542 + 'PhabricatorDashboardViewController' => 'PhabricatorDashboardProfileController', 7539 7543 'PhabricatorDataCacheSpec' => 'PhabricatorCacheSpec', 7540 7544 'PhabricatorDataNotAttachedException' => 'Exception', 7541 7545 'PhabricatorDatabaseHealthRecord' => 'Phobject',
+1
src/applications/dashboard/application/PhabricatorDashboardApplication.php
··· 27 27 'view/(?P<id>\d+)/' => 'PhabricatorDashboardViewController', 28 28 'archive/(?P<id>\d+)/' => 'PhabricatorDashboardArchiveController', 29 29 'manage/(?P<id>\d+)/' => 'PhabricatorDashboardManageController', 30 + 'arrange/(?P<id>\d+)/' => 'PhabricatorDashboardArrangeController', 30 31 'create/' => 'PhabricatorDashboardEditController', 31 32 'copy/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardCopyController', 32 33 'edit/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardEditController',
+2 -1
src/applications/dashboard/controller/PhabricatorDashboardAddPanelController.php
··· 20 20 return new Aphront404Response(); 21 21 } 22 22 23 - $redirect_uri = $this->getApplicationURI('manage/'.$dashboard->getID().'/'); 23 + $redirect_uri = $this->getApplicationURI( 24 + 'arrange/'.$dashboard->getID().'/'); 24 25 25 26 $v_panel = $request->getStr('panel'); 26 27 $e_panel = true;
+72
src/applications/dashboard/controller/PhabricatorDashboardArrangeController.php
··· 1 + <?php 2 + 3 + final class PhabricatorDashboardArrangeController 4 + extends PhabricatorDashboardProfileController { 5 + 6 + public function shouldAllowPublic() { 7 + return true; 8 + } 9 + 10 + public function handleRequest(AphrontRequest $request) { 11 + $viewer = $request->getViewer(); 12 + $id = $request->getURIData('id'); 13 + 14 + $dashboard = id(new PhabricatorDashboardQuery()) 15 + ->setViewer($viewer) 16 + ->withIDs(array($id)) 17 + ->needPanels(true) 18 + ->executeOne(); 19 + if (!$dashboard) { 20 + return new Aphront404Response(); 21 + } 22 + $this->setDashboard($dashboard); 23 + 24 + $can_edit = PhabricatorPolicyFilter::hasCapability( 25 + $viewer, 26 + $dashboard, 27 + PhabricatorPolicyCapability::CAN_EDIT); 28 + 29 + $title = $dashboard->getName(); 30 + $crumbs = $this->buildApplicationCrumbs(); 31 + $crumbs->addTextCrumb(pht('Arrange')); 32 + $header = $this->buildHeaderView(); 33 + 34 + $info_view = null; 35 + if (!$can_edit) { 36 + $no_edit = pht( 37 + 'You do not have permission to edit this dashboard. If you want to '. 38 + 'make changes, make a copy first.'); 39 + 40 + $info_view = id(new PHUIInfoView()) 41 + ->setSeverity(PHUIInfoView::SEVERITY_NOTICE) 42 + ->setErrors(array($no_edit)); 43 + } 44 + 45 + $rendered_dashboard = id(new PhabricatorDashboardRenderingEngine()) 46 + ->setViewer($viewer) 47 + ->setDashboard($dashboard) 48 + ->setArrangeMode($can_edit) 49 + ->renderDashboard(); 50 + 51 + $dashboard_box = id(new PHUIBoxView()) 52 + ->addClass('dashboard-preview-box') 53 + ->appendChild($rendered_dashboard); 54 + 55 + $view = id(new PHUITwoColumnView()) 56 + ->setHeader($header) 57 + ->setFooter(array( 58 + $info_view, 59 + $dashboard_box, 60 + )); 61 + 62 + $navigation = $this->buildSideNavView('arrange'); 63 + 64 + return $this->newPage() 65 + ->setTitle($title) 66 + ->setCrumbs($crumbs) 67 + ->setNavigation($navigation) 68 + ->appendChild($view); 69 + 70 + } 71 + 72 + }
+4 -4
src/applications/dashboard/controller/PhabricatorDashboardCopyController.php
··· 16 16 return new Aphront404Response(); 17 17 } 18 18 19 - $manage_uri = $this->getApplicationURI('manage/'.$dashboard->getID().'/'); 19 + $cancel_uri = $this->getApplicationURI('manage/'.$dashboard->getID().'/'); 20 20 21 21 if ($request->isFormPost()) { 22 22 ··· 45 45 ->setContinueOnNoEffect(true) 46 46 ->applyTransactions($copy, $xactions); 47 47 48 - $manage_uri = $this->getApplicationURI('edit/'.$copy->getID().'/'); 49 - return id(new AphrontRedirectResponse())->setURI($manage_uri); 48 + $cancel_uri = $this->getApplicationURI('edit/'.$copy->getID().'/'); 49 + return id(new AphrontRedirectResponse())->setURI($cancel_uri); 50 50 } 51 51 52 52 return $this->newDialog() ··· 55 55 pht( 56 56 'Create a copy of the dashboard "%s"?', 57 57 phutil_tag('strong', array(), $dashboard->getName()))) 58 - ->addCancelButton($manage_uri) 58 + ->addCancelButton($cancel_uri) 59 59 ->addSubmitButton(pht('Create Copy')); 60 60 } 61 61
+2 -2
src/applications/dashboard/controller/PhabricatorDashboardEditController.php
··· 117 117 ->setContentSourceFromRequest($request) 118 118 ->applyTransactions($dashboard, $xactions); 119 119 120 - $uri = $this->getApplicationURI('manage/'.$dashboard->getID().'/'); 120 + $uri = $this->getApplicationURI('arrange/'.$dashboard->getID().'/'); 121 121 122 122 return id(new AphrontRedirectResponse())->setURI($uri); 123 123 } catch (PhabricatorApplicationTransactionValidationException $ex) { ··· 351 351 ->setContentSourceFromRequest($request) 352 352 ->applyTransactions($dashboard, $xactions); 353 353 354 - $manage_uri = $this->getApplicationURI('manage/'.$dashboard->getID().'/'); 354 + $manage_uri = $this->getApplicationURI('arrange/'.$dashboard->getID().'/'); 355 355 356 356 return id(new AphrontRedirectResponse()) 357 357 ->setURI($manage_uri);
+12 -51
src/applications/dashboard/controller/PhabricatorDashboardManageController.php
··· 1 1 <?php 2 2 3 3 final class PhabricatorDashboardManageController 4 - extends PhabricatorDashboardController { 4 + extends PhabricatorDashboardProfileController { 5 + 6 + public function shouldAllowPublic() { 7 + return true; 8 + } 5 9 6 10 public function handleRequest(AphrontRequest $request) { 7 11 $viewer = $request->getViewer(); 8 12 $id = $request->getURIData('id'); 9 - 10 - $dashboard_uri = $this->getApplicationURI('view/'.$id.'/'); 11 13 12 14 // TODO: This UI should drop a lot of capabilities if the user can't 13 15 // edit the dashboard, but we should still let them in for "Install" and ··· 21 23 if (!$dashboard) { 22 24 return new Aphront404Response(); 23 25 } 26 + $this->setDashboard($dashboard); 24 27 25 28 $can_edit = PhabricatorPolicyFilter::hasCapability( 26 29 $viewer, ··· 30 33 $title = $dashboard->getName(); 31 34 32 35 $crumbs = $this->buildApplicationCrumbs(); 33 - $crumbs->addTextCrumb( 34 - pht('Dashboard %d', $dashboard->getID()), 35 - $dashboard_uri); 36 36 $crumbs->addTextCrumb(pht('Manage')); 37 - $crumbs->setBorder(true); 38 37 39 - $header = $this->buildHeaderView($dashboard); 38 + $header = $this->buildHeaderView(); 40 39 $curtain = $this->buildCurtainview($dashboard); 41 40 $properties = $this->buildPropertyView($dashboard); 42 41 43 42 $timeline = $this->buildTransactionTimeline( 44 43 $dashboard, 45 44 new PhabricatorDashboardTransactionQuery()); 45 + $timeline->setShouldTerminate(true); 46 46 47 47 $info_view = null; 48 48 if (!$can_edit) { ··· 55 55 ->setErrors(array($no_edit)); 56 56 } 57 57 58 - $rendered_dashboard = id(new PhabricatorDashboardRenderingEngine()) 59 - ->setViewer($viewer) 60 - ->setDashboard($dashboard) 61 - ->setArrangeMode($can_edit) 62 - ->renderDashboard(); 63 - 64 - $dashboard_box = id(new PHUIBoxView()) 65 - ->addClass('dashboard-preview-box') 66 - ->appendChild($rendered_dashboard); 67 - 68 58 $view = id(new PHUITwoColumnView()) 69 59 ->setHeader($header) 70 60 ->setCurtain($curtain) ··· 72 62 $info_view, 73 63 $properties, 74 64 $timeline, 75 - )) 76 - ->setFooter($dashboard_box); 65 + )); 66 + 67 + $navigation = $this->buildSideNavView('manage'); 77 68 78 69 return $this->newPage() 79 70 ->setTitle($title) 80 71 ->setCrumbs($crumbs) 72 + ->setNavigation($navigation) 81 73 ->appendChild($view); 82 74 83 - } 84 - 85 - private function buildHeaderView(PhabricatorDashboard $dashboard) { 86 - $viewer = $this->getViewer(); 87 - $id = $dashboard->getID(); 88 - 89 - if ($dashboard->isArchived()) { 90 - $status_icon = 'fa-ban'; 91 - $status_color = 'dark'; 92 - } else { 93 - $status_icon = 'fa-check'; 94 - $status_color = 'bluegrey'; 95 - } 96 - 97 - $status_name = idx( 98 - PhabricatorDashboard::getStatusNameMap(), 99 - $dashboard->getStatus()); 100 - 101 - $button = id(new PHUIButtonView()) 102 - ->setTag('a') 103 - ->setText(pht('View Dashboard')) 104 - ->setIcon('fa-columns') 105 - ->setHref($this->getApplicationURI("view/{$id}/")); 106 - 107 - return id(new PHUIHeaderView()) 108 - ->setUser($viewer) 109 - ->setHeader($dashboard->getName()) 110 - ->setPolicyObject($dashboard) 111 - ->setStatus($status_icon, $status_color, $status_name) 112 - ->setHeaderIcon($dashboard->getIcon()) 113 - ->addActionLink($button); 114 75 } 115 76 116 77 private function buildCurtainView(PhabricatorDashboard $dashboard) {
+2 -2
src/applications/dashboard/controller/PhabricatorDashboardPanelEditController.php
··· 26 26 return new Aphront404Response(); 27 27 } 28 28 29 - $manage_uri = $this->getApplicationURI('manage/'.$dashboard_id.'/'); 29 + $manage_uri = $this->getApplicationURI('arrange/'.$dashboard_id.'/'); 30 30 } 31 31 32 32 if ($id) { ··· 372 372 373 373 $viewer = $request->getUser(); 374 374 375 - $manage_uri = $this->getApplicationURI('manage/'.$dashboard->getID().'/'); 375 + $manage_uri = $this->getApplicationURI('arrange/'.$dashboard->getID().'/'); 376 376 377 377 return $this->newDialog() 378 378 ->setTitle(pht('Copy Panel?'))
+95
src/applications/dashboard/controller/PhabricatorDashboardProfileController.php
··· 1 + <?php 2 + 3 + abstract class PhabricatorDashboardProfileController 4 + extends PhabricatorController { 5 + 6 + private $dashboard; 7 + 8 + public function setDashboard(PhabricatorDashboard $dashboard) { 9 + $this->dashboard = $dashboard; 10 + return $this; 11 + } 12 + 13 + public function getDashboard() { 14 + return $this->dashboard; 15 + } 16 + 17 + public function buildApplicationMenu() { 18 + return $this->buildSideNavView()->getMenu(); 19 + } 20 + 21 + protected function buildHeaderView() { 22 + $viewer = $this->getViewer(); 23 + $dashboard = $this->getDashboard(); 24 + $id = $dashboard->getID(); 25 + 26 + if ($dashboard->isArchived()) { 27 + $status_icon = 'fa-ban'; 28 + $status_color = 'dark'; 29 + } else { 30 + $status_icon = 'fa-check'; 31 + $status_color = 'bluegrey'; 32 + } 33 + 34 + $status_name = idx( 35 + PhabricatorDashboard::getStatusNameMap(), 36 + $dashboard->getStatus()); 37 + 38 + return id(new PHUIHeaderView()) 39 + ->setUser($viewer) 40 + ->setHeader($dashboard->getName()) 41 + ->setPolicyObject($dashboard) 42 + ->setStatus($status_icon, $status_color, $status_name) 43 + ->setHeaderIcon($dashboard->getIcon()); 44 + } 45 + 46 + protected function buildApplicationCrumbs() { 47 + $dashboard = $this->getDashboard(); 48 + $id = $dashboard->getID(); 49 + $dashboard_uri = $this->getApplicationURI("/view/{$id}/"); 50 + 51 + $crumbs = parent::buildApplicationCrumbs(); 52 + $crumbs->addTextCrumb($dashboard->getName(), $dashboard_uri); 53 + $crumbs->setBorder(true); 54 + return $crumbs; 55 + } 56 + 57 + protected function buildSideNavView($filter = null) { 58 + $viewer = $this->getViewer(); 59 + $dashboard = $this->getDashboard(); 60 + $id = $dashboard->getID(); 61 + 62 + $can_edit = PhabricatorPolicyFilter::hasCapability( 63 + $viewer, 64 + $dashboard, 65 + PhabricatorPolicyCapability::CAN_EDIT); 66 + 67 + $nav = id(new AphrontSideNavFilterView()) 68 + ->setBaseURI(new PhutilURI($this->getApplicationURI())); 69 + 70 + $nav->addLabel(pht('Dashboard')); 71 + 72 + $nav->addFilter( 73 + 'view', 74 + pht('View Dashboard'), 75 + $this->getApplicationURI("/view/{$id}/"), 76 + 'fa-dashboard'); 77 + 78 + $nav->addFilter( 79 + 'arrange', 80 + pht('Arrange Panels'), 81 + $this->getApplicationURI("/arrange/{$id}/"), 82 + 'fa-columns'); 83 + 84 + $nav->addFilter( 85 + 'manage', 86 + pht('Manage Dashboard'), 87 + $this->getApplicationURI("/manage/{$id}/"), 88 + 'fa-gears'); 89 + 90 + $nav->selectFilter($filter); 91 + 92 + return $nav; 93 + } 94 + 95 + }
+1 -1
src/applications/dashboard/controller/PhabricatorDashboardRemovePanelController.php
··· 43 43 } 44 44 45 45 $redirect_uri = $this->getApplicationURI( 46 - 'manage/'.$dashboard->getID().'/'); 46 + 'arrange/'.$dashboard->getID().'/'); 47 47 $layout_config = $dashboard->getLayoutConfigObject(); 48 48 49 49 if ($request->isFormPost()) {
+23 -37
src/applications/dashboard/controller/PhabricatorDashboardViewController.php
··· 1 1 <?php 2 2 3 3 final class PhabricatorDashboardViewController 4 - extends PhabricatorDashboardController { 5 - 6 - private $id; 4 + extends PhabricatorDashboardProfileController { 7 5 8 6 public function shouldAllowPublic() { 9 7 return true; ··· 11 9 12 10 public function handleRequest(AphrontRequest $request) { 13 11 $viewer = $request->getViewer(); 14 - $this->id = $request->getURIData('id'); 12 + $id = $request->getURIData('id'); 15 13 16 14 $dashboard = id(new PhabricatorDashboardQuery()) 17 15 ->setViewer($viewer) 18 - ->withIDs(array($this->id)) 16 + ->withIDs(array($id)) 19 17 ->needPanels(true) 20 18 ->executeOne(); 21 19 if (!$dashboard) { 22 20 return new Aphront404Response(); 23 21 } 22 + $this->setDashboard($dashboard); 24 23 24 + $dashboard_uri = $this->getApplicationURI("view/{$id}/"); 25 25 $title = $dashboard->getName(); 26 26 $crumbs = $this->buildApplicationCrumbs(); 27 - $crumbs->setBorder(true); 28 - $crumbs->addTextCrumb(pht('Dashboard %d', $dashboard->getID())); 27 + $crumbs->addTextCrumb(pht('View')); 29 28 30 29 if ($dashboard->getPanelPHIDs()) { 31 30 $rendered_dashboard = id(new PhabricatorDashboardRenderingEngine()) 32 31 ->setViewer($viewer) 33 32 ->setDashboard($dashboard) 34 33 ->renderDashboard(); 34 + $content = id(new PHUIBoxView()) 35 + ->addClass('dashboard-preview-box') 36 + ->appendChild($rendered_dashboard); 35 37 } else { 36 - $rendered_dashboard = $this->buildEmptyView(); 38 + $content = id(new PHUIInfoView()) 39 + ->setSeverity(PHUIInfoView::SEVERITY_NOTICE) 40 + ->appendChild(pht('This dashboard has no panels yet.')); 37 41 } 38 42 43 + $navigation = $this->buildSideNavView('view'); 44 + $header = $this->buildHeaderView(); 45 + 46 + $view = id(new PHUITwoColumnView()) 47 + ->setHeader($header) 48 + ->setFooter(array( 49 + $content, 50 + )); 51 + 39 52 return $this->newPage() 40 53 ->setTitle($title) 41 54 ->setCrumbs($crumbs) 42 - ->appendChild($rendered_dashboard); 43 - } 44 - 45 - protected function buildApplicationCrumbs() { 46 - $crumbs = parent::buildApplicationCrumbs(); 47 - $id = $this->id; 48 - 49 - $crumbs->addAction( 50 - id(new PHUIListItemView()) 51 - ->setIcon('fa-th') 52 - ->setName(pht('Manage Dashboard')) 53 - ->setHref($this->getApplicationURI("manage/{$id}/"))); 54 - 55 - return $crumbs; 56 - } 57 - 58 - public function buildEmptyView() { 59 - $id = $this->id; 60 - $manage_uri = $this->getApplicationURI("manage/{$id}/"); 61 - 62 - return id(new PHUIInfoView()) 63 - ->setSeverity(PHUIInfoView::SEVERITY_NODATA) 64 - ->appendChild( 65 - pht('This dashboard has no panels '. 66 - 'yet. Use %s to add panels.', 67 - phutil_tag( 68 - 'a', 69 - array('href' => $manage_uri), 70 - pht('Manage Dashboard')))); 55 + ->setNavigation($navigation) 56 + ->appendChild($view); 71 57 } 72 58 73 59 }
+27 -3
src/applications/dashboard/engine/PhabricatorDashboardRenderingEngine.php
··· 81 81 } 82 82 83 83 if ($this->arrangeMode) { 84 + $footer = null; 84 85 Javelin::initBehavior( 85 86 'dashboard-move-panels', 86 87 array( 87 88 'dashboardID' => $dashboard_id, 88 89 'moveURI' => '/dashboard/movepanel/'.$dashboard->getID().'/', 89 90 )); 91 + } else { 92 + $name = $dashboard->getName(); 93 + $icon = id(new PHUIIconView()) 94 + ->setIcon($dashboard->getIcon()) 95 + ->addClass('msr'); 96 + $footer_left = phutil_tag( 97 + 'a', 98 + array( 99 + 'class' => 'dashboard-footer-name', 100 + 'href' => '/dashboard/view/'.$dashboard->getID().'/', 101 + ), 102 + array( 103 + $icon, 104 + $name, 105 + )); 106 + 107 + $footer = phutil_tag( 108 + 'div', 109 + array( 110 + 'class' => 'dashboard-footer-view', 111 + ), 112 + array( 113 + $footer_left, 114 + )); 90 115 } 91 116 92 117 $view = id(new PHUIBoxView()) 93 118 ->addClass('dashboard-view') 94 - ->appendChild($result); 119 + ->appendChild($result) 120 + ->appendChild($footer); 95 121 96 122 return $view; 97 123 } ··· 123 149 ->setTag('a') 124 150 ->setHref($create_uri) 125 151 ->setWorkflow(true) 126 - ->setColor(PHUIButtonView::GREY) 127 152 ->setText(pht('Create Panel')) 128 153 ->addClass(PHUI::MARGIN_MEDIUM); 129 154 ··· 131 156 ->setTag('a') 132 157 ->setHref($add_uri) 133 158 ->setWorkflow(true) 134 - ->setColor(PHUIButtonView::GREY) 135 159 ->setText(pht('Add Existing Panel')) 136 160 ->addClass(PHUI::MARGIN_MEDIUM); 137 161
+8 -55
src/applications/dashboard/query/PhabricatorDashboardSearchEngine.php
··· 101 101 $dashboards = mpull($dashboards, null, 'getPHID'); 102 102 $viewer = $this->requireViewer(); 103 103 104 - if ($dashboards) { 105 - $installs = id(new PhabricatorDashboardInstall()) 106 - ->loadAllWhere( 107 - 'objectPHID IN (%Ls) AND dashboardPHID IN (%Ls)', 108 - array( 109 - PhabricatorHomeApplication::DASHBOARD_DEFAULT, 110 - $viewer->getPHID(), 111 - ), 112 - array_keys($dashboards)); 113 - $installs = mpull($installs, null, 'getDashboardPHID'); 114 - } else { 115 - $installs = array(); 116 - } 117 - 118 104 $proj_phids = array(); 119 105 foreach ($dashboards as $dashboard) { 120 106 foreach ($dashboard->getProjectPHIDs() as $project_phid) { ··· 127 113 ->withPHIDs($proj_phids) 128 114 ->execute(); 129 115 130 - $list = new PHUIObjectItemListView(); 131 - $list->setUser($viewer); 132 - $list->initBehavior('phabricator-tooltips', array()); 133 - $list->requireResource('aphront-tooltip-css'); 116 + $list = id(new PHUIObjectItemListView()) 117 + ->setUser($viewer); 134 118 135 119 foreach ($dashboards as $dashboard_phid => $dashboard) { 136 120 $id = $dashboard->getID(); 137 121 138 122 $item = id(new PHUIObjectItemView()) 139 - ->setObjectName(pht('Dashboard %d', $id)) 123 + ->setUser($viewer) 140 124 ->setHeader($dashboard->getName()) 141 125 ->setHref($this->getApplicationURI("view/{$id}/")) 142 126 ->setObject($dashboard); 143 127 144 - if (isset($installs[$dashboard_phid])) { 145 - $install = $installs[$dashboard_phid]; 146 - if ($install->getObjectPHID() == $viewer->getPHID()) { 147 - $attrs = array( 148 - 'tip' => pht( 149 - 'This dashboard is installed to your personal homepage.'), 150 - ); 151 - $item->addIcon('fa-user', pht('Installed'), $attrs); 152 - } else { 153 - $attrs = array( 154 - 'tip' => pht( 155 - 'This dashboard is the default homepage for all users.'), 156 - ); 157 - $item->addIcon('fa-globe', pht('Installed'), $attrs); 158 - } 159 - } 160 - 161 128 $project_handles = array_select_keys( 162 129 $proj_handles, 163 130 $dashboard->getProjectPHIDs()); ··· 173 140 $item->setDisabled(true); 174 141 } 175 142 176 - $can_edit = PhabricatorPolicyFilter::hasCapability( 177 - $viewer, 178 - $dashboard, 179 - PhabricatorPolicyCapability::CAN_EDIT); 180 - 181 - $href_view = $this->getApplicationURI("manage/{$id}/"); 182 - $item->addAction( 183 - id(new PHUIListItemView()) 184 - ->setName(pht('Manage')) 185 - ->setIcon('fa-th') 186 - ->setHref($href_view)); 187 - 188 - $href_edit = $this->getApplicationURI("edit/{$id}/"); 189 - $item->addAction( 190 - id(new PHUIListItemView()) 191 - ->setName(pht('Edit')) 192 - ->setIcon('fa-pencil') 193 - ->setHref($href_edit) 194 - ->setDisabled(!$can_edit)); 143 + $icon = id(new PHUIIconView()) 144 + ->setIcon($dashboard->getIcon()) 145 + ->setBackground('bg-dark'); 146 + $item->setImageIcon($icon); 147 + $item->setEpoch($dashboard->getDateModified()); 195 148 196 149 $list->addItem($item); 197 150 }
+2 -2
src/applications/dashboard/storage/PhabricatorDashboardTransaction.php
··· 56 56 case self::TYPE_STATUS: 57 57 if ($new == PhabricatorDashboard::STATUS_ACTIVE) { 58 58 return pht( 59 - '%s activated this dashboard', 59 + '%s activated this dashboard.', 60 60 $author_link); 61 61 } else { 62 62 return pht( 63 - '%s archived this dashboard', 63 + '%s archived this dashboard.', 64 64 $author_link); 65 65 } 66 66 break;
+60 -35
webroot/rsrc/css/application/dashboard/dashboard.css
··· 35 35 } 36 36 37 37 .device-desktop .aphront-multi-column-fluid .aphront-multi-column-2-up 38 - .aphront-multi-column-column-outer.half { 39 - width: 50%; 38 + .aphront-multi-column-column-outer.half { 39 + width: 50%; 40 40 } 41 41 42 42 .device-desktop .aphront-multi-column-fluid .aphront-multi-column-2-up 43 - .aphront-multi-column-column-outer.third { 44 - width: 33.34%; 43 + .aphront-multi-column-column-outer.third { 44 + width: 33.34%; 45 45 } 46 46 47 47 .device-desktop .aphront-multi-column-fluid .aphront-multi-column-2-up 48 - .aphront-multi-column-column-outer.thirds { 49 - width: 66.66%; 48 + .aphront-multi-column-column-outer.thirds { 49 + width: 66.66%; 50 50 } 51 51 52 - .aphront-multi-column-fluid 53 - .aphront-multi-column-column-outer.grippable 54 - .aphront-multi-column-column .dashboard-pane { 52 + .grippable .aphront-multi-column-column .dashboard-pane .phui-object-box { 55 53 cursor: move; 56 54 } 57 55 58 - .aphront-multi-column-fluid 59 - .aphront-multi-column-column .drag-ghost { 56 + .grippable .aphront-multi-column-column .dashboard-pane .phui-object-box:hover { 57 + box-shadow: {$dropshadow}; 58 + } 59 + 60 + .grippable .aphront-multi-column-column .dashboard-pane .phui-object-box:hover 61 + .phui-object-box { 62 + box-shadow: none; 63 + } 64 + 65 + .aphront-multi-column-fluid .aphront-multi-column-column .drag-ghost { 60 66 list-style-type: none; 61 - margin: 16px; 62 67 } 63 68 64 - .aphront-multi-column-fluid 65 - .aphront-multi-column-column 66 - .dashboard-panel-placeholder { 67 - display: none; 69 + .aphront-multi-column-fluid .aphront-multi-column-column 70 + .dashboard-panel-placeholder { 71 + display: none; 68 72 } 69 73 70 - .aphront-multi-column-fluid 71 - .aphront-multi-column-column.dashboard-column-empty 72 - .dashboard-panel-placeholder { 73 - display: block; 74 - padding: 20px; 75 - margin: 0 0 12px 0; 76 - text-decoration: none; 77 - border: 1px {$greyborder} dashed; 78 - color: {$greytext}; 74 + .aphront-multi-column-fluid .aphront-multi-column-column.dashboard-column-empty 75 + .dashboard-panel-placeholder { 76 + display: block; 77 + padding: 20px; 78 + margin: 0 0 12px 0; 79 + text-decoration: none; 80 + border: 1px {$greyborder} dashed; 81 + color: {$greytext}; 79 82 } 80 83 81 - .aphront-multi-column-fluid 82 - .aphront-multi-column-column.drag-target-list 83 - .dashboard-panel-placeholder { 84 - display: none; 84 + .aphront-multi-column-fluid .aphront-multi-column-column.drag-target-list 85 + .dashboard-panel-placeholder { 86 + display: none; 85 87 } 86 88 87 - .aphront-multi-column-fluid 88 - .aphront-multi-column-column-outer 89 - .aphront-multi-column-column .phui-info-view { 90 - margin: 0; 89 + .aphront-multi-column-fluid .aphront-multi-column-column-outer 90 + .aphront-multi-column-column .phui-info-view { 91 + margin: 0; 91 92 } 92 93 93 94 .dashboard-preview-box { 94 - border: 1px solid {$lightblueborder}; 95 + margin: -16px -16px 16px; 96 + } 97 + 98 + .phui-info-view + .dashboard-preview-box { 99 + margin-top: 0; 100 + } 101 + 102 + .drag-frame .phui-object-box { 103 + box-shadow: {$dropshadow}; 104 + } 105 + 106 + .drag-frame .phui-object-box .phui-object-box { 107 + box-shadow: none; 108 + } 109 + 110 + /*** Footer *******************************************************************/ 111 + 112 + .dashboard-footer-view { 113 + background-color: {$page.sidenav}; 114 + padding: 8px 16px; 95 115 border-radius: 3px; 96 - background-color: rgba(255,255,255,.33); 116 + } 117 + 118 + .dashboard-footer-name { 119 + color: {$darkbluetext}; 120 + font-weight: bold; 121 + -webkit-font-smoothing: antialiased; 97 122 }
+4
webroot/rsrc/css/application/search/application-search-view.css
··· 67 67 .device-phone .application-search-pager { 68 68 margin: 12px; 69 69 } 70 + 71 + .application-search-view .phui-oi-list-view.phui-oi-list-big { 72 + margin-top: 12px; 73 + }