mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-03 20:22:46 +01:00
(stable) Allow menu items to render their own content; make Dashboard items render on-page
Summary: Ref T11957. When you click a dashboard item, it now sends you to `/<app>/item/view/123/`, which renders the proper crumbs, navigation, etc., with the dashboard as page content. This works as you'd expect in Projects: {F2508568} It's sliiiightly odd in Favorites since we nuke the nav menu, but seems basically fine? {F2508571} Test Plan: - Created a dashboard panel on a project. - Clicked it, saw it render. - Made it the default panel, viewed project default screen, saw dashboard. - Disabled every panel I could, still saw reasonable behavior (this is silly anyway). Reviewers: chad Reviewed By: chad Maniphest Tasks: T11957 Differential Revision: https://secure.phabricator.com/D17255
This commit is contained in:
parent
23c54262ca
commit
2dc4692021
10 changed files with 113 additions and 27 deletions
|
@ -7,7 +7,7 @@ final class PhabricatorFavoritesProfileMenuEngine
|
|||
return true;
|
||||
}
|
||||
|
||||
protected function getItemURI($path) {
|
||||
public function getItemURI($path) {
|
||||
$object = $this->getProfileObject();
|
||||
$custom = $this->getCustomPHID();
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ final class PhabricatorHomeProfileMenuEngine
|
|||
return true;
|
||||
}
|
||||
|
||||
protected function getItemURI($path) {
|
||||
public function getItemURI($path) {
|
||||
$object = $this->getProfileObject();
|
||||
$custom = $this->getCustomPHID();
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ final class PhabricatorPeopleProfileMenuEngine
|
|||
return false;
|
||||
}
|
||||
|
||||
protected function getItemURI($path) {
|
||||
public function getItemURI($path) {
|
||||
$user = $this->getProfileObject();
|
||||
$username = $user->getUsername();
|
||||
$username = phutil_escape_uri($username);
|
||||
|
|
|
@ -25,9 +25,10 @@ final class PhabricatorProjectViewController
|
|||
$controller_object = new PhabricatorProjectBoardViewController();
|
||||
break;
|
||||
case PhabricatorProject::ITEM_PROFILE:
|
||||
default:
|
||||
$controller_object = new PhabricatorProjectProfileController();
|
||||
break;
|
||||
default:
|
||||
return $engine->buildResponse();
|
||||
}
|
||||
|
||||
return $this->delegateToController($controller_object);
|
||||
|
|
|
@ -7,7 +7,7 @@ final class PhabricatorProjectProfileMenuEngine
|
|||
return true;
|
||||
}
|
||||
|
||||
protected function getItemURI($path) {
|
||||
public function getItemURI($path) {
|
||||
$project = $this->getProfileObject();
|
||||
$id = $project->getID();
|
||||
return "/project/{$id}/item/{$path}";
|
||||
|
|
|
@ -18,11 +18,6 @@ final class PhabricatorProjectManageProfileMenuItem
|
|||
return false;
|
||||
}
|
||||
|
||||
public function canMakeDefault(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDisplayName(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
$name = $config->getMenuItemProperty('name');
|
||||
|
|
|
@ -82,7 +82,7 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
return $this->showNavigation;
|
||||
}
|
||||
|
||||
abstract protected function getItemURI($path);
|
||||
abstract public function getItemURI($path);
|
||||
abstract protected function isMenuEngineConfigurable();
|
||||
|
||||
abstract protected function getBuiltinProfileItems($object);
|
||||
|
@ -102,6 +102,9 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
$request = $controller->getRequest();
|
||||
|
||||
$item_action = $request->getURIData('itemAction');
|
||||
if (!$item_action) {
|
||||
$item_action = 'view';
|
||||
}
|
||||
|
||||
// If the engine is not configurable, don't respond to any of the editing
|
||||
// or configuration routes.
|
||||
|
@ -136,6 +139,12 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
}
|
||||
}
|
||||
|
||||
if (!$selected_item) {
|
||||
if ($item_action == 'view') {
|
||||
$selected_item = $this->getDefaultItem();
|
||||
}
|
||||
}
|
||||
|
||||
switch ($item_action) {
|
||||
case 'view':
|
||||
case 'info':
|
||||
|
@ -159,21 +168,33 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
}
|
||||
|
||||
$navigation = $this->buildNavigation();
|
||||
$navigation->selectFilter('item.configure');
|
||||
|
||||
$crumbs = $controller->buildApplicationCrumbsForEditEngine();
|
||||
switch ($this->getMenuType()) {
|
||||
case 'personal':
|
||||
$crumbs->addTextCrumb(pht('Personal'));
|
||||
break;
|
||||
case 'global':
|
||||
$crumbs->addTextCrumb(pht('Global'));
|
||||
break;
|
||||
|
||||
// TODO: This stuff might need a little tweaking at some point, since it
|
||||
// causes "Global" and "Personal" to show up in contexts where they don't
|
||||
// make sense, notably Projects.
|
||||
if ($item_action != 'view') {
|
||||
$navigation->selectFilter('item.configure');
|
||||
switch ($this->getMenuType()) {
|
||||
case 'personal':
|
||||
$crumbs->addTextCrumb(pht('Personal'));
|
||||
break;
|
||||
case 'global':
|
||||
$crumbs->addTextCrumb(pht('Global'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch ($item_action) {
|
||||
case 'view':
|
||||
$navigation->selectFilter($selected_item->getItemIdentifier());
|
||||
|
||||
$content = $this->buildItemViewContent($selected_item);
|
||||
$crumbs->addTextCrumb($selected_item->getDisplayName());
|
||||
if (!$content) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
break;
|
||||
case 'configure':
|
||||
$content = $this->buildItemConfigureContent($item_list);
|
||||
|
@ -225,6 +246,7 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
if ($this->getShowNavigation()) {
|
||||
$page->setNavigation($navigation);
|
||||
}
|
||||
|
||||
return $page;
|
||||
}
|
||||
|
||||
|
@ -269,13 +291,8 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
if (count($items) == 1) {
|
||||
$item = head($items);
|
||||
if ($item->getKey() === null) {
|
||||
$builtin_key = $menu_item->getBuiltinKey();
|
||||
$item_phid = $menu_item->getPHID();
|
||||
if ($builtin_key !== null) {
|
||||
$item->setKey($builtin_key);
|
||||
} else if ($item_phid !== null) {
|
||||
$item->setKey($item_phid);
|
||||
}
|
||||
$item_identifier = $menu_item->getItemIdentifier();
|
||||
$item->setKey($item_identifier);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -326,6 +343,7 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
foreach ($stored_items as $stored_item) {
|
||||
$impl = $stored_item->getMenuItem();
|
||||
$impl->setViewer($viewer);
|
||||
$impl->setEngine($this);
|
||||
}
|
||||
|
||||
// Merge the stored items into the builtin items. If a builtin item has
|
||||
|
@ -442,6 +460,7 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
|
||||
$item = clone $item;
|
||||
$item->setViewer($viewer);
|
||||
$item->setEngine($this);
|
||||
|
||||
$builtin
|
||||
->setProfilePHID($object->getPHID())
|
||||
|
@ -546,6 +565,10 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
|
|||
->setURI($this->getConfigureURI());
|
||||
}
|
||||
|
||||
private function buildItemViewContent(
|
||||
PhabricatorProfileMenuItemConfiguration $item) {
|
||||
return $item->newPageContent();
|
||||
}
|
||||
|
||||
private function buildItemConfigureContent(array $items) {
|
||||
$viewer = $this->getViewer();
|
||||
|
|
|
@ -21,6 +21,11 @@ final class PhabricatorDashboardProfileMenuItem
|
|||
return true;
|
||||
}
|
||||
|
||||
public function canMakeDefault(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function attachDashboard($dashboard) {
|
||||
$this->dashboard = $dashboard;
|
||||
return $this;
|
||||
|
@ -28,14 +33,39 @@ final class PhabricatorDashboardProfileMenuItem
|
|||
|
||||
public function getDashboard() {
|
||||
$dashboard = $this->dashboard;
|
||||
|
||||
if (!$dashboard) {
|
||||
return null;
|
||||
} else if ($dashboard->isArchived()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $dashboard;
|
||||
}
|
||||
|
||||
public function newPageContent(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$dashboard_phid = $config->getMenuItemProperty('dashboardPHID');
|
||||
|
||||
// Reload the dashboard to attach panels, which we need for rendering.
|
||||
$dashboard = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($dashboard_phid))
|
||||
->needPanels(true)
|
||||
->executeOne();
|
||||
if (!$dashboard) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$engine = id(new PhabricatorDashboardRenderingEngine())
|
||||
->setViewer($viewer)
|
||||
->setDashboard($dashboard);
|
||||
|
||||
return $engine->renderDashboard();
|
||||
}
|
||||
|
||||
public function willBuildNavigationItems(array $items) {
|
||||
$viewer = $this->getViewer();
|
||||
$dashboard_phids = array();
|
||||
|
@ -100,7 +130,7 @@ final class PhabricatorDashboardProfileMenuItem
|
|||
|
||||
$icon = $dashboard->getIcon();
|
||||
$name = $this->getDisplayName($config);
|
||||
$href = $dashboard->getViewURI();
|
||||
$href = $this->getItemViewURI($config);
|
||||
|
||||
$item = $this->newItem()
|
||||
->setHref($href)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
abstract class PhabricatorProfileMenuItem extends Phobject {
|
||||
|
||||
private $viewer;
|
||||
private $engine;
|
||||
|
||||
final public function buildNavigationMenuItems(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
|
@ -55,6 +56,15 @@ abstract class PhabricatorProfileMenuItem extends Phobject {
|
|||
return $this->viewer;
|
||||
}
|
||||
|
||||
public function setEngine(PhabricatorProfileMenuEngine $engine) {
|
||||
$this->engine = $engine;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getEngine() {
|
||||
return $this->engine;
|
||||
}
|
||||
|
||||
final public function getMenuItemKey() {
|
||||
return $this->getPhobjectClassConstant('MENUITEMKEY');
|
||||
}
|
||||
|
@ -70,6 +80,20 @@ abstract class PhabricatorProfileMenuItem extends Phobject {
|
|||
return new PHUIListItemView();
|
||||
}
|
||||
|
||||
public function newPageContent(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getItemViewURI(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
|
||||
$engine = $this->getEngine();
|
||||
$key = $config->getItemIdentifier();
|
||||
|
||||
return $engine->getItemURI("view/{$key}/");
|
||||
}
|
||||
|
||||
public function validateTransactions(
|
||||
PhabricatorProfileMenuItemConfiguration $config,
|
||||
$field_key,
|
||||
|
|
|
@ -185,6 +185,19 @@ final class PhabricatorProfileMenuItemConfiguration
|
|||
return ($this->getVisibility() === self::VISIBILITY_DEFAULT);
|
||||
}
|
||||
|
||||
public function getItemIdentifier() {
|
||||
$id = $this->getID();
|
||||
|
||||
if ($id) {
|
||||
return (int)$id;
|
||||
}
|
||||
|
||||
return $this->getBuiltinKey();
|
||||
}
|
||||
|
||||
public function newPageContent() {
|
||||
return $this->getMenuItem()->newPageContent($this);
|
||||
}
|
||||
|
||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||
|
||||
|
|
Loading…
Reference in a new issue