From f23bfccc046775bf369064c549d6f877e212ced2 Mon Sep 17 00:00:00 2001 From: epriestley Date: Tue, 31 Jan 2017 10:48:03 -0800 Subject: [PATCH] Replace ProfileMenu bugs with different bugs Summary: Ref T12174. This fixes more bugs than it creates, I think: - Dashboards now show the whole menu. - Project and home items now show selected state correctly. - The "choose global vs personal" thing is now part of MenuEngine, and the same code builds it for Home and Favorites. - Home now handles defaults correctly, I think. Maybe regression/bad/still buggy?: - Mobile home is now whatever the default thing was, not the menu? - Title for dashboard content or other items that render their own content is incorrectly always "Configure Menu" (this was preexisting). Test Plan: - Created, edited, reordered, disabled, deleted and pinned personal and global items on home, favorites, and projects. - Also checked User profiles. Reviewers: chad Reviewed By: chad Maniphest Tasks: T12174 Differential Revision: https://secure.phabricator.com/D17273 --- src/__phutil_library_map__.php | 12 +- .../base/PhabricatorApplication.php | 8 +- .../PhabricatorFavoritesApplication.php | 3 +- .../PhabricatorFavoritesMainController.php | 63 ----- ...PhabricatorFavoritesMenuItemController.php | 10 +- .../PhabricatorFavoritesProfileMenuEngine.php | 9 +- ...abricatorFavoritesMainMenuBarExtension.php | 14 +- .../PhabricatorHomeApplication.php | 9 +- .../controller/PhabricatorHomeController.php | 10 +- .../PhabricatorHomeMenuController.php | 62 ---- .../PhabricatorHomeMenuItemController.php | 18 +- .../PhabricatorHomeProfileMenuEngine.php | 15 +- .../PhabricatorHomeProfileMenuItem.php | 9 +- .../PHUIHomeView.php} | 53 +--- .../PhabricatorProjectProfileMenuEngine.php | 8 +- .../engine/PhabricatorProfileMenuEngine.php | 266 ++++++++++++++---- .../PhabricatorDashboardProfileMenuItem.php | 6 +- .../PhabricatorManageProfileMenuItem.php} | 28 +- ...catorProfileMenuItemConfigurationQuery.php | 1 + ...habricatorProfileMenuItemConfiguration.php | 8 + 20 files changed, 298 insertions(+), 314 deletions(-) delete mode 100644 src/applications/favorites/controller/PhabricatorFavoritesMainController.php delete mode 100644 src/applications/home/controller/PhabricatorHomeMenuController.php rename src/applications/home/{controller/PhabricatorHomeMainController.php => view/PHUIHomeView.php} (82%) rename src/applications/{home/menuitem/PhabricatorHomeManageProfileMenuItem.php => search/menuitem/PhabricatorManageProfileMenuItem.php} (73%) diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index df3772dae9..0b4e41c126 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1687,6 +1687,7 @@ phutil_register_library_map(array( 'PHUIHandleView' => 'applications/phid/view/PHUIHandleView.php', 'PHUIHeadThingView' => 'view/phui/PHUIHeadThingView.php', 'PHUIHeaderView' => 'view/phui/PHUIHeaderView.php', + 'PHUIHomeView' => 'applications/home/view/PHUIHomeView.php', 'PHUIHovercardUIExample' => 'applications/uiexample/examples/PHUIHovercardUIExample.php', 'PHUIHovercardView' => 'view/phui/PHUIHovercardView.php', 'PHUIIconCircleView' => 'view/phui/PHUIIconCircleView.php', @@ -2676,7 +2677,6 @@ phutil_register_library_map(array( 'PhabricatorFactUpdateIterator' => 'applications/fact/extract/PhabricatorFactUpdateIterator.php', 'PhabricatorFavoritesApplication' => 'applications/favorites/application/PhabricatorFavoritesApplication.php', 'PhabricatorFavoritesController' => 'applications/favorites/controller/PhabricatorFavoritesController.php', - 'PhabricatorFavoritesMainController' => 'applications/favorites/controller/PhabricatorFavoritesMainController.php', 'PhabricatorFavoritesMainMenuBarExtension' => 'applications/favorites/engineextension/PhabricatorFavoritesMainMenuBarExtension.php', 'PhabricatorFavoritesMenuItemController' => 'applications/favorites/controller/PhabricatorFavoritesMenuItemController.php', 'PhabricatorFavoritesProfileMenuEngine' => 'applications/favorites/engine/PhabricatorFavoritesProfileMenuEngine.php', @@ -2839,9 +2839,6 @@ phutil_register_library_map(array( 'PhabricatorHomeConstants' => 'applications/home/constants/PhabricatorHomeConstants.php', 'PhabricatorHomeController' => 'applications/home/controller/PhabricatorHomeController.php', 'PhabricatorHomeLauncherProfileMenuItem' => 'applications/home/menuitem/PhabricatorHomeLauncherProfileMenuItem.php', - 'PhabricatorHomeMainController' => 'applications/home/controller/PhabricatorHomeMainController.php', - 'PhabricatorHomeManageProfileMenuItem' => 'applications/home/menuitem/PhabricatorHomeManageProfileMenuItem.php', - 'PhabricatorHomeMenuController' => 'applications/home/controller/PhabricatorHomeMenuController.php', 'PhabricatorHomeMenuItemController' => 'applications/home/controller/PhabricatorHomeMenuItemController.php', 'PhabricatorHomeProfileMenuEngine' => 'applications/home/engine/PhabricatorHomeProfileMenuEngine.php', 'PhabricatorHomeProfileMenuItem' => 'applications/home/menuitem/PhabricatorHomeProfileMenuItem.php', @@ -2964,6 +2961,7 @@ phutil_register_library_map(array( 'PhabricatorMainMenuBarExtension' => 'view/page/menu/PhabricatorMainMenuBarExtension.php', 'PhabricatorMainMenuSearchView' => 'view/page/menu/PhabricatorMainMenuSearchView.php', 'PhabricatorMainMenuView' => 'view/page/menu/PhabricatorMainMenuView.php', + 'PhabricatorManageProfileMenuItem' => 'applications/search/menuitem/PhabricatorManageProfileMenuItem.php', 'PhabricatorManagementWorkflow' => 'infrastructure/management/PhabricatorManagementWorkflow.php', 'PhabricatorManiphestApplication' => 'applications/maniphest/application/PhabricatorManiphestApplication.php', 'PhabricatorManiphestConfigOptions' => 'applications/maniphest/config/PhabricatorManiphestConfigOptions.php', @@ -6563,6 +6561,7 @@ phutil_register_library_map(array( 'PHUIHandleView' => 'AphrontView', 'PHUIHeadThingView' => 'AphrontTagView', 'PHUIHeaderView' => 'AphrontTagView', + 'PHUIHomeView' => 'AphrontTagView', 'PHUIHovercardUIExample' => 'PhabricatorUIExample', 'PHUIHovercardView' => 'AphrontTagView', 'PHUIIconCircleView' => 'AphrontTagView', @@ -7698,7 +7697,6 @@ phutil_register_library_map(array( 'PhabricatorFactUpdateIterator' => 'PhutilBufferedIterator', 'PhabricatorFavoritesApplication' => 'PhabricatorApplication', 'PhabricatorFavoritesController' => 'PhabricatorController', - 'PhabricatorFavoritesMainController' => 'PhabricatorFavoritesController', 'PhabricatorFavoritesMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension', 'PhabricatorFavoritesMenuItemController' => 'PhabricatorFavoritesController', 'PhabricatorFavoritesProfileMenuEngine' => 'PhabricatorProfileMenuEngine', @@ -7897,9 +7895,6 @@ phutil_register_library_map(array( 'PhabricatorHomeConstants' => 'PhabricatorHomeController', 'PhabricatorHomeController' => 'PhabricatorController', 'PhabricatorHomeLauncherProfileMenuItem' => 'PhabricatorProfileMenuItem', - 'PhabricatorHomeMainController' => 'PhabricatorHomeController', - 'PhabricatorHomeManageProfileMenuItem' => 'PhabricatorProfileMenuItem', - 'PhabricatorHomeMenuController' => 'PhabricatorHomeController', 'PhabricatorHomeMenuItemController' => 'PhabricatorHomeController', 'PhabricatorHomeProfileMenuEngine' => 'PhabricatorProfileMenuEngine', 'PhabricatorHomeProfileMenuItem' => 'PhabricatorProfileMenuItem', @@ -8022,6 +8017,7 @@ phutil_register_library_map(array( 'PhabricatorMainMenuBarExtension' => 'Phobject', 'PhabricatorMainMenuSearchView' => 'AphrontView', 'PhabricatorMainMenuView' => 'AphrontView', + 'PhabricatorManageProfileMenuItem' => 'PhabricatorProfileMenuItem', 'PhabricatorManagementWorkflow' => 'PhutilArgumentWorkflow', 'PhabricatorManiphestApplication' => 'PhabricatorApplication', 'PhabricatorManiphestConfigOptions' => 'PhabricatorApplicationConfigOptions', diff --git a/src/applications/base/PhabricatorApplication.php b/src/applications/base/PhabricatorApplication.php index caf2dd4612..b791aaeef8 100644 --- a/src/applications/base/PhabricatorApplication.php +++ b/src/applications/base/PhabricatorApplication.php @@ -596,14 +596,18 @@ abstract class PhabricatorApplication protected function getProfileMenuRouting($controller) { $edit_route = $this->getEditRoutePattern(); + $mode_route = '(?Pglobal|custom)/'; + return array( '(?Pview)/(?P[^/]+)/' => $controller, '(?Phide)/(?P[^/]+)/' => $controller, '(?Pdefault)/(?P[^/]+)/' => $controller, '(?Pconfigure)/' => $controller, - '(?Preorder)/' => $controller, + '(?Pconfigure)/'.$mode_route => $controller, + '(?Preorder)/'.$mode_route => $controller, '(?Pedit)/'.$edit_route => $controller, - '(?Pnew)/(?[^/]+)/'.$edit_route => $controller, + '(?Pnew)/'.$mode_route.'(?[^/]+)/'.$edit_route + => $controller, '(?Pbuiltin)/(?[^/]+)/'.$edit_route => $controller, ); diff --git a/src/applications/favorites/application/PhabricatorFavoritesApplication.php b/src/applications/favorites/application/PhabricatorFavoritesApplication.php index 1d5d3ae2aa..3a6acd4ebc 100644 --- a/src/applications/favorites/application/PhabricatorFavoritesApplication.php +++ b/src/applications/favorites/application/PhabricatorFavoritesApplication.php @@ -21,8 +21,7 @@ final class PhabricatorFavoritesApplication extends PhabricatorApplication { public function getRoutes() { return array( '/favorites/' => array( - '' => 'PhabricatorFavoritesMainController', - '(?Pglobal|personal)/item/' => $this->getProfileMenuRouting( + 'menu/' => $this->getProfileMenuRouting( 'PhabricatorFavoritesMenuItemController'), ), ); diff --git a/src/applications/favorites/controller/PhabricatorFavoritesMainController.php b/src/applications/favorites/controller/PhabricatorFavoritesMainController.php deleted file mode 100644 index 54197a6635..0000000000 --- a/src/applications/favorites/controller/PhabricatorFavoritesMainController.php +++ /dev/null @@ -1,63 +0,0 @@ -getViewer(); - - if (!$viewer->getIsAdmin()) { - $uri = '/favorites/personal/item/configure/'; - return id(new AphrontRedirectResponse())->setURI($uri); - } - - $menu = id(new PHUIObjectItemListView()) - ->setUser($viewer); - - $menu->addItem( - id(new PHUIObjectItemView()) - ->setHeader(pht('Personal Menu Items')) - ->setHref($this->getApplicationURI('personal/item/configure/')) - ->setImageURI($viewer->getProfileImageURI()) - ->addAttribute(pht('Edit favorites for your personal account.'))); - - $icon = id(new PHUIIconView()) - ->setIcon('fa-globe') - ->setBackground('bg-blue'); - - $menu->addItem( - id(new PHUIObjectItemView()) - ->setHeader(pht('Global Menu Items')) - ->setHref($this->getApplicationURI('global/item/configure/')) - ->setImageIcon($icon) - ->addAttribute(pht('Edit global default favorites for all users.'))); - - $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb(pht('Manage')); - $crumbs->setBorder(true); - - $box = id(new PHUIObjectBoxView()) - ->setObjectList($menu); - - $header = id(new PHUIHeaderView()) - ->setHeader(pht('Manage Favorites')) - ->setHeaderIcon('fa-star-o'); - - $view = id(new PHUITwoColumnView()) - ->setHeader($header) - ->setFooter(array( - $box, - )); - - return $this->newPage() - ->setTitle(pht('Manage')) - ->setCrumbs($crumbs) - ->appendChild($view); - - } - -} diff --git a/src/applications/favorites/controller/PhabricatorFavoritesMenuItemController.php b/src/applications/favorites/controller/PhabricatorFavoritesMenuItemController.php index 912d9efe0d..dd4bf77cf0 100644 --- a/src/applications/favorites/controller/PhabricatorFavoritesMenuItemController.php +++ b/src/applications/favorites/controller/PhabricatorFavoritesMenuItemController.php @@ -5,13 +5,6 @@ final class PhabricatorFavoritesMenuItemController public function handleRequest(AphrontRequest $request) { $viewer = $this->getViewer(); - $type = $request->getURIData('type'); - $custom_phid = null; - $menu = PhabricatorProfileMenuEngine::MENU_GLOBAL; - if ($type == 'personal') { - $custom_phid = $viewer->getPHID(); - $menu = PhabricatorProfileMenuEngine::MENU_PERSONAL; - } $application = 'PhabricatorFavoritesApplication'; $favorites = id(new PhabricatorApplicationQuery()) @@ -22,9 +15,8 @@ final class PhabricatorFavoritesMenuItemController $engine = id(new PhabricatorFavoritesProfileMenuEngine()) ->setProfileObject($favorites) - ->setCustomPHID($custom_phid) + ->setCustomPHID($viewer->getPHID()) ->setController($this) - ->setMenuType($menu) ->setShowNavigation(false); return $engine->buildResponse(); diff --git a/src/applications/favorites/engine/PhabricatorFavoritesProfileMenuEngine.php b/src/applications/favorites/engine/PhabricatorFavoritesProfileMenuEngine.php index 87b59e3e0f..0ac31e7de8 100644 --- a/src/applications/favorites/engine/PhabricatorFavoritesProfileMenuEngine.php +++ b/src/applications/favorites/engine/PhabricatorFavoritesProfileMenuEngine.php @@ -8,14 +8,7 @@ final class PhabricatorFavoritesProfileMenuEngine } public function getItemURI($path) { - $object = $this->getProfileObject(); - $custom = $this->getCustomPHID(); - - if ($custom) { - return "/favorites/personal/item/{$path}"; - } else { - return "/favorites/global/item/{$path}"; - } + return "/favorites/menu/{$path}"; } protected function getBuiltinProfileItems($object) { diff --git a/src/applications/favorites/engineextension/PhabricatorFavoritesMainMenuBarExtension.php b/src/applications/favorites/engineextension/PhabricatorFavoritesMainMenuBarExtension.php index 990ecad993..63d8726857 100644 --- a/src/applications/favorites/engineextension/PhabricatorFavoritesMainMenuBarExtension.php +++ b/src/applications/favorites/engineextension/PhabricatorFavoritesMainMenuBarExtension.php @@ -50,16 +50,8 @@ final class PhabricatorFavoritesMainMenuBarExtension $menu_engine = id(new PhabricatorFavoritesProfileMenuEngine()) ->setViewer($viewer) - ->setProfileObject($favorites); - - if ($viewer->getPHID()) { - $menu_engine - ->setCustomPHID($viewer->getPHID()) - ->setMenuType(PhabricatorProfileMenuEngine::MENU_COMBINED); - } else { - $menu_engine - ->setMenuType(PhabricatorProfileMenuEngine::MENU_GLOBAL); - } + ->setProfileObject($favorites) + ->setCustomPHID($viewer->getPHID()); $filter_view = $menu_engine->buildNavigation(); @@ -87,7 +79,7 @@ final class PhabricatorFavoritesMainMenuBarExtension $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Favorites')) - ->setHref('/favorites/')); + ->setHref('/favorites/menu/configure/')); } return $view; diff --git a/src/applications/home/application/PhabricatorHomeApplication.php b/src/applications/home/application/PhabricatorHomeApplication.php index a860bc8fb3..7743f70c0e 100644 --- a/src/applications/home/application/PhabricatorHomeApplication.php +++ b/src/applications/home/application/PhabricatorHomeApplication.php @@ -22,14 +22,11 @@ final class PhabricatorHomeApplication extends PhabricatorApplication { public function getRoutes() { return array( - '/' => 'PhabricatorHomeMainController', - '/(?Phome)/' => 'PhabricatorHomeMainController', + '/' => 'PhabricatorHomeMenuItemController', '/home/' => array( - 'menu/' => array( - '' => 'PhabricatorHomeMenuController', - '(?Pglobal|personal)/item/' => $this->getProfileMenuRouting( + '' => 'PhabricatorHomeMenuItemController', + 'menu/' => $this->getProfileMenuRouting( 'PhabricatorHomeMenuItemController'), - ), ), ); } diff --git a/src/applications/home/controller/PhabricatorHomeController.php b/src/applications/home/controller/PhabricatorHomeController.php index ffb27b3a2e..7c46525ee0 100644 --- a/src/applications/home/controller/PhabricatorHomeController.php +++ b/src/applications/home/controller/PhabricatorHomeController.php @@ -31,14 +31,8 @@ abstract class PhabricatorHomeController extends PhabricatorController { $engine = id(new PhabricatorHomeProfileMenuEngine()) ->setViewer($viewer) - ->setProfileObject($home); - - if ($viewer->getPHID()) { - $engine->setCustomPHID($viewer->getPHID()) - ->setMenuType(PhabricatorProfileMenuEngine::MENU_COMBINED); - } else { - $engine->setMenuType(PhabricatorProfileMenuEngine::MENU_GLOBAL); - } + ->setProfileObject($home) + ->setCustomPHID($viewer->getPHID()); $this->profileMenu = $engine->buildNavigation(); } diff --git a/src/applications/home/controller/PhabricatorHomeMenuController.php b/src/applications/home/controller/PhabricatorHomeMenuController.php deleted file mode 100644 index 7e3ef8b14d..0000000000 --- a/src/applications/home/controller/PhabricatorHomeMenuController.php +++ /dev/null @@ -1,62 +0,0 @@ -getViewer(); - - if (!$viewer->getIsAdmin()) { - $uri = '/home/menu/personal/item/configure/'; - return id(new AphrontRedirectResponse())->setURI($uri); - } - - $menu = id(new PHUIObjectItemListView()) - ->setUser($viewer); - - $menu->addItem( - id(new PHUIObjectItemView()) - ->setHeader(pht('Personal Menu Items')) - ->setHref($this->getApplicationURI('menu/personal/item/configure/')) - ->setImageURI($viewer->getProfileImageURI()) - ->addAttribute(pht('Edit the menu for your personal account.'))); - - $icon = id(new PHUIIconView()) - ->setIcon('fa-globe') - ->setBackground('bg-blue'); - - $menu->addItem( - id(new PHUIObjectItemView()) - ->setHeader(pht('Global Menu Items')) - ->setHref($this->getApplicationURI('menu/global/item/configure/')) - ->setImageIcon($icon) - ->addAttribute(pht('Edit the global default menu for all users.'))); - - $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb(pht('Manage')); - $crumbs->setBorder(true); - - $box = id(new PHUIObjectBoxView()) - ->setObjectList($menu); - - $header = id(new PHUIHeaderView()) - ->setHeader(pht('Manage Home Menu')) - ->setHeaderIcon('fa-home'); - - $view = id(new PHUITwoColumnView()) - ->setHeader($header) - ->setFooter(array( - $box, - )); - - return $this->newPage() - ->setTitle(pht('Manage Home Menu')) - ->setCrumbs($crumbs) - ->appendChild($view); - - } - -} diff --git a/src/applications/home/controller/PhabricatorHomeMenuItemController.php b/src/applications/home/controller/PhabricatorHomeMenuItemController.php index 5649b947d6..f0e436ddd9 100644 --- a/src/applications/home/controller/PhabricatorHomeMenuItemController.php +++ b/src/applications/home/controller/PhabricatorHomeMenuItemController.php @@ -3,14 +3,21 @@ final class PhabricatorHomeMenuItemController extends PhabricatorHomeController { + public function shouldAllowPublic() { + return true; + } + + public function isGlobalDragAndDropUploadEnabled() { + return true; + } + public function handleRequest(AphrontRequest $request) { $viewer = $this->getViewer(); - $type = $request->getURIData('type'); - $custom_phid = null; - $menu = PhabricatorProfileMenuEngine::MENU_GLOBAL; - if ($type == 'personal') { + + if ($viewer->getPHID()) { $custom_phid = $viewer->getPHID(); - $menu = PhabricatorProfileMenuEngine::MENU_PERSONAL; + } else { + $custom_phid = null; } $application = 'PhabricatorHomeApplication'; @@ -23,7 +30,6 @@ final class PhabricatorHomeMenuItemController $engine = id(new PhabricatorHomeProfileMenuEngine()) ->setProfileObject($home_app) ->setCustomPHID($custom_phid) - ->setMenuType($menu) ->setController($this); return $engine->buildResponse(); diff --git a/src/applications/home/engine/PhabricatorHomeProfileMenuEngine.php b/src/applications/home/engine/PhabricatorHomeProfileMenuEngine.php index c8c04947a8..8fd141c951 100644 --- a/src/applications/home/engine/PhabricatorHomeProfileMenuEngine.php +++ b/src/applications/home/engine/PhabricatorHomeProfileMenuEngine.php @@ -8,14 +8,7 @@ final class PhabricatorHomeProfileMenuEngine } public function getItemURI($path) { - $object = $this->getProfileObject(); - $custom = $this->getCustomPHID(); - - if ($custom) { - return "/home/menu/personal/item/{$path}"; - } else { - return "/home/menu/global/item/{$path}"; - } + return "/home/menu/{$path}"; } protected function getBuiltinProfileItems($object) { @@ -58,11 +51,7 @@ final class PhabricatorHomeProfileMenuEngine ->setMenuItemKey( PhabricatorHomeLauncherProfileMenuItem::MENUITEMKEY); - // Single Manage Item, switches URI based on admin/user - $items[] = $this->newItem() - ->setBuiltinKey(PhabricatorHomeConstants::ITEM_MANAGE) - ->setMenuItemKey( - PhabricatorHomeManageProfileMenuItem::MENUITEMKEY); + $items[] = $this->newManageItem(); return $items; } diff --git a/src/applications/home/menuitem/PhabricatorHomeProfileMenuItem.php b/src/applications/home/menuitem/PhabricatorHomeProfileMenuItem.php index 1283ff3d34..ab77fa9098 100644 --- a/src/applications/home/menuitem/PhabricatorHomeProfileMenuItem.php +++ b/src/applications/home/menuitem/PhabricatorHomeProfileMenuItem.php @@ -34,6 +34,13 @@ final class PhabricatorHomeProfileMenuItem return $this->getDefaultName(); } + public function newPageContent() { + $viewer = $this->getViewer(); + + return id(new PHUIHomeView()) + ->setViewer($viewer); + } + public function buildEditEngineFields( PhabricatorProfileMenuItemConfiguration $config) { return array( @@ -52,7 +59,7 @@ final class PhabricatorHomeProfileMenuItem if ($viewer->isLoggedIn()) { $name = $this->getDisplayName($config); $icon = 'fa-home'; - $href = '/home/'; + $href = $this->getItemViewURI($config); $item = $this->newItem() ->setHref($href) diff --git a/src/applications/home/controller/PhabricatorHomeMainController.php b/src/applications/home/view/PHUIHomeView.php similarity index 82% rename from src/applications/home/controller/PhabricatorHomeMainController.php rename to src/applications/home/view/PHUIHomeView.php index 79687af51f..e68643f6d3 100644 --- a/src/applications/home/controller/PhabricatorHomeMainController.php +++ b/src/applications/home/view/PHUIHomeView.php @@ -1,52 +1,23 @@ getViewer(); - - $dashboard = PhabricatorDashboardInstall::getDashboard( - $viewer, - $viewer->getPHID(), - get_class($this->getCurrentApplication())); - - if (!$dashboard) { - $dashboard = PhabricatorDashboardInstall::getDashboard( - $viewer, - PhabricatorHomeApplication::DASHBOARD_DEFAULT, - get_class($this->getCurrentApplication())); - } - - if ($dashboard) { - $content = id(new PhabricatorDashboardRenderingEngine()) - ->setViewer($viewer) - ->setDashboard($dashboard) - ->renderDashboard(); - } else { - $content = $this->buildMainResponse(); - } - - $nav = $this->getProfileMenu(); - $content = - array( - $content, - id(new PhabricatorGlobalUploadTargetView())->setUser($viewer), - ); - - return $this->newPage() - ->setTitle('Phabricator') - ->addClass('phabricator-home') - ->setNavigation($nav) - ->appendChild($content); + protected function getTagContent() { + $viewer = $this->getViewer(); + return array( + $this->buildMainResponse(), + id(new PhabricatorGlobalUploadTargetView())->setUser($viewer), + ); } private function buildMainResponse() { diff --git a/src/applications/project/engine/PhabricatorProjectProfileMenuEngine.php b/src/applications/project/engine/PhabricatorProjectProfileMenuEngine.php index a39e7a8236..534db15113 100644 --- a/src/applications/project/engine/PhabricatorProjectProfileMenuEngine.php +++ b/src/applications/project/engine/PhabricatorProjectProfileMenuEngine.php @@ -7,6 +7,10 @@ final class PhabricatorProjectProfileMenuEngine return true; } + protected function isMenuEnginePersonalizable() { + return false; + } + public function getItemURI($path) { $project = $this->getProfileObject(); $id = $project->getID(); @@ -37,9 +41,7 @@ final class PhabricatorProjectProfileMenuEngine ->setMenuItemKey( PhabricatorProjectSubprojectsProfileMenuItem::MENUITEMKEY); - $items[] = $this->newItem() - ->setBuiltinKey(PhabricatorProject::ITEM_MANAGE) - ->setMenuItemKey(PhabricatorProjectManageProfileMenuItem::MENUITEMKEY); + $items[] = $this->newManageItem(); return $items; } diff --git a/src/applications/search/engine/PhabricatorProfileMenuEngine.php b/src/applications/search/engine/PhabricatorProfileMenuEngine.php index 04aa7c574f..6f0b1542eb 100644 --- a/src/applications/search/engine/PhabricatorProfileMenuEngine.php +++ b/src/applications/search/engine/PhabricatorProfileMenuEngine.php @@ -6,16 +6,18 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { private $profileObject; private $customPHID; private $items; - private $menuType = self::MENU_GLOBAL; private $defaultItem; private $controller; private $navigation; private $showNavigation = true; + private $editMode; - const MENU_GLOBAL = 'global'; - const MENU_PERSONAL = 'personal'; - const MENU_COMBINED = 'menu'; const ITEM_CUSTOM_DIVIDER = 'engine.divider'; + const ITEM_MANAGE = 'item.configure'; + + const MODE_COMBINED = 'combined'; + const MODE_GLOBAL = 'global'; + const MODE_CUSTOM = 'custom'; public function setViewer(PhabricatorUser $viewer) { $this->viewer = $viewer; @@ -44,6 +46,21 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { return $this->customPHID; } + private function getEditModeCustomPHID() { + $mode = $this->getEditMode(); + + switch ($mode) { + case self::MODE_CUSTOM: + $custom_phid = $this->getCustomPHID(); + break; + case self::MODE_GLOBAL: + $custom_phid = null; + break; + } + + return $custom_phid; + } + public function setController(PhabricatorController $controller) { $this->controller = $controller; return $this; @@ -60,19 +77,10 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { } public function getDefaultItem() { - $this->loadItems(); + $this->getItems(); return $this->defaultItem; } - public function setMenuType($type) { - $this->menuType = $type; - return $this; - } - - private function getMenuType() { - return $this->menuType; - } - public function setShowNavigation($show) { $this->showNavigation = $show; return $this; @@ -93,6 +101,10 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { return array(); } + protected function getEditMode() { + return $this->editMode; + } + public function buildResponse() { $controller = $this->getController(); @@ -171,24 +183,35 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { $crumbs = $controller->buildApplicationCrumbsForEditEngine(); - // 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; + $navigation->selectFilter(self::ITEM_MANAGE); + + if ($selected_item) { + if ($selected_item->getCustomPHID()) { + $edit_mode = 'custom'; + } else { + $edit_mode = 'global'; + } + } else { + $edit_mode = $request->getURIData('itemEditMode'); + } + + $available_modes = $this->getViewerEditModes($viewer); + if ($available_modes) { + $available_modes = array_fuse($available_modes); + if (isset($available_modes[$edit_mode])) { + $this->editMode = $edit_mode; + } else { + if ($item_action != 'configure') { + return new Aphront404Response(); + } + } } } switch ($item_action) { case 'view': - $navigation->selectFilter($selected_item->getItemIdentifier()); + $navigation->selectFilter($selected_item->getDefaultMenuItemKey()); $content = $this->buildItemViewContent($selected_item); $crumbs->addTextCrumb($selected_item->getDisplayName()); @@ -197,15 +220,40 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { } break; case 'configure': - $content = $this->buildItemConfigureContent($item_list); - $crumbs->addTextCrumb(pht('Configure Menu')); + $mode = $this->getEditMode(); + if (!$mode) { + $crumbs->addTextCrumb(pht('Configure Menu')); + $content = $this->buildMenuEditModeContent(); + } else { + if (count($available_modes) > 1) { + $crumbs->addTextCrumb( + pht('Configure Menu'), + $this->getItemURI('configure/')); + + switch ($mode) { + case self::MODE_CUSTOM: + $crumbs->addTextCrumb(pht('Personal')); + break; + case self::MODE_GLOBAL: + $crumbs->addTextCrumb(pht('Global')); + break; + } + } else { + $crumbs->addTextCrumb(pht('Configure Menu')); + } + $edit_list = $this->loadItems($mode); + $content = $this->buildItemConfigureContent($edit_list); + } break; case 'reorder': - $content = $this->buildItemReorderContent($item_list); + $mode = $this->getEditMode(); + $edit_list = $this->loadItems($mode); + $content = $this->buildItemReorderContent($edit_list); break; case 'new': $item_key = $request->getURIData('itemKey'); - $content = $this->buildItemNewContent($item_key); + $mode = $this->getEditMode(); + $content = $this->buildItemNewContent($item_key, $mode); break; case 'builtin': $content = $this->buildItemBuiltinContent($selected_item); @@ -238,6 +286,8 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { $crumbs->setBorder(true); + // TODO: This title is not correct when viewing items. + $page = $controller->newPage() ->setTitle(pht('Configure Menu')) ->setCrumbs($crumbs) @@ -290,8 +340,8 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { if (count($items) == 1) { $item = head($items); if ($item->getKey() === null) { - $item_identifier = $menu_item->getItemIdentifier(); - $item->setKey($item_identifier); + $default_key = $menu_item->getDefaultMenuItemKey(); + $item->setKey($default_key); } } @@ -308,31 +358,30 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { private function getItems() { if ($this->items === null) { - $this->items = $this->loadItems(); + $this->items = $this->loadItems(self::MODE_COMBINED); } return $this->items; } - private function loadItems() { + private function loadItems($mode) { $viewer = $this->getViewer(); $object = $this->getProfileObject(); - $items = $this->loadBuiltinProfileItems(); + $items = $this->loadBuiltinProfileItems($mode); $query = id(new PhabricatorProfileMenuItemConfigurationQuery()) ->setViewer($viewer) ->withProfilePHIDs(array($object->getPHID())); - $menu_type = $this->getMenuType(); - switch ($menu_type) { - case self::MENU_GLOBAL: + switch ($mode) { + case self::MODE_GLOBAL: $query->withCustomPHIDs(array(), true); break; - case self::MENU_PERSONAL: + case self::MODE_CUSTOM: $query->withCustomPHIDs(array($this->getCustomPHID()), false); break; - case self::MENU_COMBINED: + case self::MODE_COMBINED: $query->withCustomPHIDs(array($this->getCustomPHID()), true); break; } @@ -368,7 +417,7 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { } } - $items = $this->arrangeItems($items); + $items = $this->arrangeItems($items, $mode); // Make sure exactly one valid item is marked as default. $default = null; @@ -399,20 +448,19 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { return $items; } - private function loadBuiltinProfileItems() { + private function loadBuiltinProfileItems($mode) { $object = $this->getProfileObject(); - $menu_type = $this->getMenuType(); - switch ($menu_type) { - case self::MENU_GLOBAL: + switch ($mode) { + case self::MODE_GLOBAL: $builtins = $this->getBuiltinProfileItems($object); break; - case self::MENU_PERSONAL: + case self::MODE_CUSTOM: $builtins = $this->getBuiltinCustomProfileItems( $object, $this->getCustomPHID()); break; - case self::MENU_COMBINED: + case self::MODE_COMBINED: $builtins = array(); $builtins[] = $this->getBuiltinCustomProfileItems( $object, @@ -489,6 +537,15 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { } public function getConfigureURI() { + $mode = $this->getEditMode(); + + switch ($mode) { + case self::MODE_CUSTOM: + return $this->getItemURI('configure/custom/'); + case self::MODE_GLOBAL: + return $this->getItemURI('configure/global/'); + } + return $this->getItemURI('configure/'); } @@ -500,7 +557,8 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { // object the menu appears on. If you're reordering custom items, you only // need to be able to edit the custom object. Currently, the custom object // is always the viewing user's own user object. - $custom_phid = $this->getCustomPHID(); + $custom_phid = $this->getEditModeCustomPHID(); + if (!$custom_phid) { PhabricatorPolicyFilter::requireCapability( $viewer, @@ -593,6 +651,85 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { return $item->newPageContent(); } + private function getViewerEditModes() { + $modes = array(); + + $viewer = $this->getViewer(); + + if ($viewer->isLoggedIn() && $this->isMenuEnginePersonalizable()) { + $modes[] = self::MODE_CUSTOM; + } + + $object = $this->getProfileObject(); + $can_edit = PhabricatorPolicyFilter::hasCapability( + $viewer, + $object, + PhabricatorPolicyCapability::CAN_EDIT); + + if ($can_edit) { + $modes[] = self::MODE_GLOBAL; + } + + return $modes; + } + + protected function isMenuEnginePersonalizable() { + return true; + } + + private function buildMenuEditModeContent() { + $viewer = $this->getViewer(); + + $modes = $this->getViewerEditModes($viewer); + if (!$modes) { + return new Aphront404Response(); + } + + if (count($modes) == 1) { + $mode = head($modes); + return id(new AphrontRedirectResponse()) + ->setURI($this->getItemURI("configure/{$mode}/")); + } + + $menu = id(new PHUIObjectItemListView()) + ->setUser($viewer); + + $modes = array_fuse($modes); + + if (isset($modes['custom'])) { + $menu->addItem( + id(new PHUIObjectItemView()) + ->setHeader(pht('Personal Menu Items')) + ->setHref($this->getItemURI('configure/custom/')) + ->setImageURI($viewer->getProfileImageURI()) + ->addAttribute(pht('Edit the menu for your personal account.'))); + } + + if (isset($modes['global'])) { + $icon = id(new PHUIIconView()) + ->setIcon('fa-globe') + ->setBackground('bg-blue'); + + $menu->addItem( + id(new PHUIObjectItemView()) + ->setHeader(pht('Global Menu Items')) + ->setHref($this->getItemURI('configure/global/')) + ->setImageIcon($icon) + ->addAttribute(pht('Edit the global default menu for all users.'))); + } + + $box = id(new PHUIObjectBoxView()) + ->setObjectList($menu); + + $header = id(new PHUIHeaderView()) + ->setHeader(pht('Manage Menu')) + ->setHeaderIcon('fa-list'); + + return id(new PHUITwoColumnView()) + ->setHeader($header) + ->setFooter($box); + } + private function buildItemConfigureContent(array $items) { $viewer = $this->getViewer(); $object = $this->getProfileObject(); @@ -616,11 +753,13 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { $list_id = celerity_generate_unique_node_id(); + $mode = $this->getEditMode(); + Javelin::initBehavior( 'reorder-profile-menu-items', array( 'listID' => $list_id, - 'orderURI' => $this->getItemURI('reorder/'), + 'orderURI' => $this->getItemURI("reorder/{$mode}/"), )); $list = id(new PHUIObjectItemListView()) @@ -738,12 +877,13 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { } $item_key = $item_type->getMenuItemKey(); + $edit_mode = $this->getEditMode(); $action_list->addAction( id(new PhabricatorActionView()) ->setIcon($item_type->getMenuItemTypeIcon()) ->setName($item_type->getMenuItemTypeName()) - ->setHref($this->getItemURI("new/{$item_key}/")) + ->setHref($this->getItemURI("new/{$edit_mode}/{$item_key}/")) ->setWorkflow(true)); } @@ -788,7 +928,7 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { return $view; } - private function buildItemNewContent($item_key) { + private function buildItemNewContent($item_key, $mode) { $item_types = PhabricatorProfileMenuItem::getAllMenuItems(); $item_type = idx($item_types, $item_key); if (!$item_type) { @@ -800,7 +940,8 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { return new Aphront404Response(); } - $custom_phid = $this->getCustomPHID(); + $custom_phid = $this->getEditModeCustomPHID(); + $configuration = PhabricatorProfileMenuItemConfiguration::initializeNewItem( $object, $item_type, @@ -828,12 +969,13 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { $viewer = $this->getViewer(); $object = $this->getProfileObject(); $controller = $this->getController(); + $custom_phid = $this->getEditModeCustomPHID(); return id(new PhabricatorProfileMenuEditEngine()) ->setMenuEngine($this) ->setProfileObject($object) ->setController($controller) - ->setCustomPHID($this->getCustomPHID()) + ->setCustomPHID($custom_phid) ->buildResponse(); } @@ -859,6 +1001,7 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { $object = $this->getProfileObject(); $controller = $this->getController(); + $custom_phid = $this->getEditModeCustomPHID(); return id(new PhabricatorProfileMenuEditEngine()) ->setIsBuiltin(true) @@ -866,7 +1009,7 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { ->setProfileObject($object) ->setNewMenuItemConfiguration($configuration) ->setController($controller) - ->setCustomPHID($this->getCustomPHID()) + ->setCustomPHID($custom_phid) ->buildResponse(); } @@ -1008,12 +1151,18 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { return PhabricatorProfileMenuItemConfiguration::initializeNewBuiltin(); } + protected function newManageItem() { + return $this->newItem() + ->setBuiltinKey(self::ITEM_MANAGE) + ->setMenuItemKey(PhabricatorManageProfileMenuItem::MENUITEMKEY); + } + public function adjustDefault($key) { $controller = $this->getController(); $request = $controller->getRequest(); $viewer = $request->getViewer(); - $items = $this->loadItems(); + $items = $this->loadItems(self::MODE_COMBINED); // To adjust the default item, we first change any existing items that // are marked as defaults to "visible", then make the new default item @@ -1074,13 +1223,15 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { return $this; } - private function arrangeItems(array $items) { + private function arrangeItems(array $items, $mode) { // Sort the items. $items = msortv($items, 'getSortVector'); + $object = $this->getProfileObject(); + // If we have some global items and some custom items and are in "combined" // mode, put a hard-coded divider item between them. - if ($this->getMenuType() == self::MENU_COMBINED) { + if ($mode == self::MODE_COMBINED) { $list = array(); $seen_custom = false; $seen_global = false; @@ -1092,6 +1243,7 @@ abstract class PhabricatorProfileMenuEngine extends Phobject { $list[] = $this->newItem() ->setBuiltinKey(self::ITEM_CUSTOM_DIVIDER) ->setMenuItemKey(PhabricatorDividerProfileMenuItem::MENUITEMKEY) + ->attachProfileObject($object) ->attachMenuItem( new PhabricatorDividerProfileMenuItem()); } diff --git a/src/applications/search/menuitem/PhabricatorDashboardProfileMenuItem.php b/src/applications/search/menuitem/PhabricatorDashboardProfileMenuItem.php index 002e5778d5..c442a2cc46 100644 --- a/src/applications/search/menuitem/PhabricatorDashboardProfileMenuItem.php +++ b/src/applications/search/menuitem/PhabricatorDashboardProfileMenuItem.php @@ -60,8 +60,8 @@ final class PhabricatorDashboardProfileMenuItem } $engine = id(new PhabricatorDashboardRenderingEngine()) - ->setViewer($viewer) - ->setDashboard($dashboard); + ->setViewer($viewer) + ->setDashboard($dashboard); return $engine->renderDashboard(); } @@ -89,9 +89,11 @@ final class PhabricatorDashboardProfileMenuItem public function getDisplayName( PhabricatorProfileMenuItemConfiguration $config) { $dashboard = $this->getDashboard(); + if (!$dashboard) { return pht('(Restricted/Invalid Dashboard)'); } + if (strlen($this->getName($config))) { return $this->getName($config); } else { diff --git a/src/applications/home/menuitem/PhabricatorHomeManageProfileMenuItem.php b/src/applications/search/menuitem/PhabricatorManageProfileMenuItem.php similarity index 73% rename from src/applications/home/menuitem/PhabricatorHomeManageProfileMenuItem.php rename to src/applications/search/menuitem/PhabricatorManageProfileMenuItem.php index fbca14f527..d5de555975 100644 --- a/src/applications/home/menuitem/PhabricatorHomeManageProfileMenuItem.php +++ b/src/applications/search/menuitem/PhabricatorManageProfileMenuItem.php @@ -1,12 +1,12 @@ getViewer(); - if ($viewer->isLoggedIn()) { - $name = $this->getDisplayName($config); - $icon = 'fa-pencil'; - $href = '/home/menu/'; - - $item = $this->newItem() - ->setHref($href) - ->setName($name) - ->setIcon($icon); + if (!$viewer->isLoggedIn()) { + return array(); } + $engine = $this->getEngine(); + $href = $engine->getItemURI('configure/'); + + $name = $this->getDisplayName($config); + $icon = 'fa-pencil'; + + $item = $this->newItem() + ->setHref($href) + ->setName($name) + ->setIcon($icon); + return array( $item, ); diff --git a/src/applications/search/query/PhabricatorProfileMenuItemConfigurationQuery.php b/src/applications/search/query/PhabricatorProfileMenuItemConfigurationQuery.php index 83a84ac306..230989e88e 100644 --- a/src/applications/search/query/PhabricatorProfileMenuItemConfigurationQuery.php +++ b/src/applications/search/query/PhabricatorProfileMenuItemConfigurationQuery.php @@ -117,6 +117,7 @@ final class PhabricatorProfileMenuItemConfigurationQuery unset($page[$key]); continue; } + $item->attachProfileObject($profile); } diff --git a/src/applications/search/storage/PhabricatorProfileMenuItemConfiguration.php b/src/applications/search/storage/PhabricatorProfileMenuItemConfiguration.php index f178cc49fe..37124393fb 100644 --- a/src/applications/search/storage/PhabricatorProfileMenuItemConfiguration.php +++ b/src/applications/search/storage/PhabricatorProfileMenuItemConfiguration.php @@ -195,6 +195,14 @@ final class PhabricatorProfileMenuItemConfiguration return $this->getBuiltinKey(); } + public function getDefaultMenuItemKey() { + if ($this->getBuiltinKey()) { + return $this->getBuiltinKey(); + } + + return $this->getPHID(); + } + public function newPageContent() { return $this->getMenuItem()->newPageContent($this); }