mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-23 05:50:55 +01:00
Move Favorites and User menus to MenuBarExtensions
Summary: Ref T12140. The major effect of this change is that uninstalling "Home" (as we do on admin.phacility.com) no longer uninstalls the user menu (which is required to access settings or log out). This also simplifies the code a bit, by consolidating how menus are built into MenuBarExtensions instead of some in Applications and some in Extensions. Test Plan: - While logged in and logged out, saw main menus in the correct order. - Uninstalled Favorites, saw the menu vanish. - Uninstalled Home, still had a user menu. Reviewers: chad Reviewed By: chad Maniphest Tasks: T12140 Differential Revision: https://secure.phabricator.com/D17239
This commit is contained in:
parent
ddf82a815b
commit
402b6473d8
9 changed files with 231 additions and 220 deletions
|
@ -1785,6 +1785,7 @@ phutil_register_library_map(array(
|
|||
'PeopleBrowseUserDirectoryCapability' => 'applications/people/capability/PeopleBrowseUserDirectoryCapability.php',
|
||||
'PeopleCreateUsersCapability' => 'applications/people/capability/PeopleCreateUsersCapability.php',
|
||||
'PeopleHovercardEngineExtension' => 'applications/people/engineextension/PeopleHovercardEngineExtension.php',
|
||||
'PeopleMainMenuBarExtension' => 'applications/people/engineextension/PeopleMainMenuBarExtension.php',
|
||||
'PeopleUserLogGarbageCollector' => 'applications/people/garbagecollector/PeopleUserLogGarbageCollector.php',
|
||||
'Phabricator404Controller' => 'applications/base/controller/Phabricator404Controller.php',
|
||||
'PhabricatorAWSConfigOptions' => 'applications/config/option/PhabricatorAWSConfigOptions.php',
|
||||
|
@ -2671,6 +2672,7 @@ phutil_register_library_map(array(
|
|||
'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',
|
||||
'PhabricatorFaxContentSource' => 'infrastructure/contentsource/PhabricatorFaxContentSource.php',
|
||||
|
@ -6662,6 +6664,7 @@ phutil_register_library_map(array(
|
|||
'PeopleBrowseUserDirectoryCapability' => 'PhabricatorPolicyCapability',
|
||||
'PeopleCreateUsersCapability' => 'PhabricatorPolicyCapability',
|
||||
'PeopleHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension',
|
||||
'PeopleMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension',
|
||||
'PeopleUserLogGarbageCollector' => 'PhabricatorGarbageCollector',
|
||||
'Phabricator404Controller' => 'PhabricatorController',
|
||||
'PhabricatorAWSConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||
|
@ -7685,6 +7688,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorFavoritesApplication' => 'PhabricatorApplication',
|
||||
'PhabricatorFavoritesController' => 'PhabricatorController',
|
||||
'PhabricatorFavoritesMainController' => 'PhabricatorFavoritesController',
|
||||
'PhabricatorFavoritesMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension',
|
||||
'PhabricatorFavoritesMenuItemController' => 'PhabricatorFavoritesController',
|
||||
'PhabricatorFavoritesProfileMenuEngine' => 'PhabricatorProfileMenuEngine',
|
||||
'PhabricatorFaxContentSource' => 'PhabricatorContentSource',
|
||||
|
|
|
@ -9,6 +9,10 @@ final class PhabricatorAuthMainMenuBarExtension
|
|||
return true;
|
||||
}
|
||||
|
||||
public function getExtensionOrder() {
|
||||
return 900;
|
||||
}
|
||||
|
||||
public function buildMainMenus() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
|
|
|
@ -315,23 +315,6 @@ abstract class PhabricatorApplication
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Build extra items for the main menu. Generally, this is used to render
|
||||
* static dropdowns.
|
||||
*
|
||||
* @param PhabricatorUser The viewing user.
|
||||
* @param AphrontController The current controller. May be null for special
|
||||
* pages like 404, exception handlers, etc.
|
||||
* @return view List of menu items.
|
||||
* @task ui
|
||||
*/
|
||||
public function buildMainMenuExtraNodes(
|
||||
PhabricatorUser $viewer,
|
||||
PhabricatorController $controller = null) {
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
/* -( Application Management )--------------------------------------------- */
|
||||
|
||||
|
||||
|
|
|
@ -32,82 +32,4 @@ final class PhabricatorFavoritesApplication extends PhabricatorApplication {
|
|||
return false;
|
||||
}
|
||||
|
||||
public function buildMainMenuExtraNodes(
|
||||
PhabricatorUser $viewer,
|
||||
PhabricatorController $controller = null) {
|
||||
|
||||
$dropdown = $this->renderFavoritesDropdown($viewer);
|
||||
if (!$dropdown) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setHref('#')
|
||||
->setIcon('fa-star')
|
||||
->addClass('phabricator-core-user-menu')
|
||||
->setNoCSS(true)
|
||||
->setDropdown(true)
|
||||
->setDropdownMenu($dropdown);
|
||||
}
|
||||
|
||||
private function renderFavoritesDropdown(PhabricatorUser $viewer) {
|
||||
$application = __CLASS__;
|
||||
|
||||
$applications = id(new PhabricatorApplicationQuery())
|
||||
->setViewer($viewer)
|
||||
->withClasses(array($application))
|
||||
->withInstalled(true)
|
||||
->execute();
|
||||
$favorites = head($applications);
|
||||
if (!$favorites) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$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);
|
||||
}
|
||||
|
||||
$filter_view = $menu_engine->buildNavigation();
|
||||
|
||||
$menu_view = $filter_view->getMenu();
|
||||
$item_views = $menu_view->getItems();
|
||||
|
||||
$view = id(new PhabricatorActionListView())
|
||||
->setViewer($viewer);
|
||||
foreach ($item_views as $item) {
|
||||
$type = null;
|
||||
if (!strlen($item->getName())) {
|
||||
$type = PhabricatorActionView::TYPE_DIVIDER;
|
||||
}
|
||||
$action = id(new PhabricatorActionView())
|
||||
->setName($item->getName())
|
||||
->setHref($item->getHref())
|
||||
->setType($type);
|
||||
$view->addAction($action);
|
||||
}
|
||||
|
||||
// Build out edit interface
|
||||
if ($viewer->isLoggedIn()) {
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setType(PhabricatorActionView::TYPE_DIVIDER));
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Favorites'))
|
||||
->setHref('/favorites/'));
|
||||
}
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorFavoritesMainMenuBarExtension
|
||||
extends PhabricatorMainMenuBarExtension {
|
||||
|
||||
const MAINMENUBARKEY = 'favorites';
|
||||
|
||||
public function isExtensionEnabledForViewer(PhabricatorUser $viewer) {
|
||||
return PhabricatorApplication::isClassInstalledForViewer(
|
||||
'PhabricatorFavoritesApplication',
|
||||
$viewer);
|
||||
}
|
||||
|
||||
public function getExtensionOrder() {
|
||||
return 1100;
|
||||
}
|
||||
|
||||
public function buildMainMenus() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$dropdown = $this->newDropdown($viewer);
|
||||
if (!$dropdown) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$favorites_menu = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setHref('#')
|
||||
->setIcon('fa-star')
|
||||
->addClass('phabricator-core-user-menu')
|
||||
->setNoCSS(true)
|
||||
->setDropdown(true)
|
||||
->setDropdownMenu($dropdown);
|
||||
|
||||
return array(
|
||||
$favorites_menu,
|
||||
);
|
||||
}
|
||||
|
||||
private function newDropdown(PhabricatorUser $viewer) {
|
||||
$applications = id(new PhabricatorApplicationQuery())
|
||||
->setViewer($viewer)
|
||||
->withClasses(array('PhabricatorFavoritesApplication'))
|
||||
->withInstalled(true)
|
||||
->execute();
|
||||
$favorites = head($applications);
|
||||
if (!$favorites) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$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);
|
||||
}
|
||||
|
||||
$filter_view = $menu_engine->buildNavigation();
|
||||
|
||||
$menu_view = $filter_view->getMenu();
|
||||
$item_views = $menu_view->getItems();
|
||||
|
||||
$view = id(new PhabricatorActionListView())
|
||||
->setViewer($viewer);
|
||||
foreach ($item_views as $item) {
|
||||
$type = null;
|
||||
if (!strlen($item->getName())) {
|
||||
$type = PhabricatorActionView::TYPE_DIVIDER;
|
||||
}
|
||||
$action = id(new PhabricatorActionView())
|
||||
->setName($item->getName())
|
||||
->setHref($item->getHref())
|
||||
->setType($type);
|
||||
$view->addAction($action);
|
||||
}
|
||||
|
||||
if ($viewer->isLoggedIn()) {
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setType(PhabricatorActionView::TYPE_DIVIDER));
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Favorites'))
|
||||
->setHref('/favorites/'));
|
||||
}
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
}
|
|
@ -42,114 +42,4 @@ final class PhabricatorHomeApplication extends PhabricatorApplication {
|
|||
return 9;
|
||||
}
|
||||
|
||||
public function buildMainMenuExtraNodes(
|
||||
PhabricatorUser $viewer,
|
||||
PhabricatorController $controller = null) {
|
||||
|
||||
if (!$viewer->isLoggedIn()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$image = $viewer->getProfileImageURI();
|
||||
|
||||
$profile_image = id(new PHUIIconView())
|
||||
->setImage($image)
|
||||
->setHeadSize(PHUIIconView::HEAD_SMALL);
|
||||
|
||||
if ($controller) {
|
||||
$application = $controller->getCurrentApplication();
|
||||
} else {
|
||||
$application = null;
|
||||
}
|
||||
$dropdown_menu = $this->renderUserDropdown($viewer, $application);
|
||||
|
||||
$menu_id = celerity_generate_unique_node_id();
|
||||
|
||||
Javelin::initBehavior(
|
||||
'user-menu',
|
||||
array(
|
||||
'menuID' => $menu_id,
|
||||
'menu' => $dropdown_menu->getDropdownMenuMetadata(),
|
||||
));
|
||||
|
||||
return id(new PHUIButtonView())
|
||||
->setID($menu_id)
|
||||
->setTag('a')
|
||||
->setHref('/p/'.$viewer->getUsername().'/')
|
||||
->setIcon($profile_image)
|
||||
->addClass('phabricator-core-user-menu')
|
||||
->setHasCaret(true)
|
||||
->setNoCSS(true);
|
||||
}
|
||||
|
||||
private function renderUserDropdown(
|
||||
PhabricatorUser $viewer,
|
||||
$application) {
|
||||
|
||||
$person_to_show = id(new PHUIObjectItemView())
|
||||
->setObjectName($viewer->getRealName())
|
||||
->setSubHead($viewer->getUsername())
|
||||
->setImageURI($viewer->getProfileImageURI());
|
||||
|
||||
$user_view = id(new PHUIObjectItemListView())
|
||||
->setViewer($viewer)
|
||||
->setFlush(true)
|
||||
->setSimple(true)
|
||||
->addItem($person_to_show)
|
||||
->addClass('phabricator-core-user-profile-object');
|
||||
|
||||
$view = id(new PhabricatorActionListView())
|
||||
->setViewer($viewer);
|
||||
|
||||
// User Menu
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->appendChild($user_view));
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setType(PhabricatorActionView::TYPE_DIVIDER));
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Profile'))
|
||||
->setHref('/p/'.$viewer->getUsername().'/'));
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Settings'))
|
||||
->setHref('/settings/user/'.$viewer->getUsername().'/'));
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Manage'))
|
||||
->setHref('/people/manage/'.$viewer->getID().'/'));
|
||||
|
||||
// Help Menus
|
||||
if ($application) {
|
||||
$help_links = $application->getHelpMenuItems($viewer);
|
||||
if ($help_links) {
|
||||
foreach ($help_links as $link) {
|
||||
$view->addAction($link);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Logout Menu
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->addSigil('logout-item')
|
||||
->setType(PhabricatorActionView::TYPE_DIVIDER));
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Log Out %s', $viewer->getUsername()))
|
||||
->addSigil('logout-item')
|
||||
->setHref('/logout/')
|
||||
->setColor(PhabricatorActionView::RED)
|
||||
->setWorkflow(true));
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
final class PeopleMainMenuBarExtension
|
||||
extends PhabricatorMainMenuBarExtension {
|
||||
|
||||
const MAINMENUBARKEY = 'user';
|
||||
|
||||
public function isExtensionEnabledForViewer(PhabricatorUser $viewer) {
|
||||
return $viewer->isLoggedIn();
|
||||
}
|
||||
|
||||
public function getExtensionOrder() {
|
||||
return 1200;
|
||||
}
|
||||
|
||||
public function buildMainMenus() {
|
||||
$viewer = $this->getViewer();
|
||||
$application = $this->getApplication();
|
||||
$dropdown_menu = $this->newDropdown($viewer, $application);
|
||||
|
||||
$menu_id = celerity_generate_unique_node_id();
|
||||
|
||||
Javelin::initBehavior(
|
||||
'user-menu',
|
||||
array(
|
||||
'menuID' => $menu_id,
|
||||
'menu' => $dropdown_menu->getDropdownMenuMetadata(),
|
||||
));
|
||||
|
||||
$image = $viewer->getProfileImageURI();
|
||||
$profile_image = id(new PHUIIconView())
|
||||
->setImage($image)
|
||||
->setHeadSize(PHUIIconView::HEAD_SMALL);
|
||||
|
||||
$user_menu = id(new PHUIButtonView())
|
||||
->setID($menu_id)
|
||||
->setTag('a')
|
||||
->setHref('/p/'.$viewer->getUsername().'/')
|
||||
->setIcon($profile_image)
|
||||
->addClass('phabricator-core-user-menu')
|
||||
->setHasCaret(true)
|
||||
->setNoCSS(true);
|
||||
|
||||
return array(
|
||||
$user_menu,
|
||||
);
|
||||
}
|
||||
|
||||
private function newDropdown(
|
||||
PhabricatorUser $viewer,
|
||||
$application) {
|
||||
|
||||
$person_to_show = id(new PHUIObjectItemView())
|
||||
->setObjectName($viewer->getRealName())
|
||||
->setSubHead($viewer->getUsername())
|
||||
->setImageURI($viewer->getProfileImageURI());
|
||||
|
||||
$user_view = id(new PHUIObjectItemListView())
|
||||
->setViewer($viewer)
|
||||
->setFlush(true)
|
||||
->setSimple(true)
|
||||
->addItem($person_to_show)
|
||||
->addClass('phabricator-core-user-profile-object');
|
||||
|
||||
$view = id(new PhabricatorActionListView())
|
||||
->setViewer($viewer);
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->appendChild($user_view));
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setType(PhabricatorActionView::TYPE_DIVIDER));
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Profile'))
|
||||
->setHref('/p/'.$viewer->getUsername().'/'));
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Settings'))
|
||||
->setHref('/settings/user/'.$viewer->getUsername().'/'));
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Manage'))
|
||||
->setHref('/people/manage/'.$viewer->getID().'/'));
|
||||
|
||||
if ($application) {
|
||||
$help_links = $application->getHelpMenuItems($viewer);
|
||||
if ($help_links) {
|
||||
foreach ($help_links as $link) {
|
||||
$view->addAction($link);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->addSigil('logout-item')
|
||||
->setType(PhabricatorActionView::TYPE_DIVIDER));
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Log Out %s', $viewer->getUsername()))
|
||||
->addSigil('logout-item')
|
||||
->setHref('/logout/')
|
||||
->setColor(PhabricatorActionView::RED)
|
||||
->setWorkflow(true));
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
}
|
|
@ -64,12 +64,17 @@ abstract class PhabricatorMainMenuBarExtension extends Phobject {
|
|||
return true;
|
||||
}
|
||||
|
||||
public function getExtensionOrder() {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
abstract public function buildMainMenus();
|
||||
|
||||
final public static function getAllExtensions() {
|
||||
return id(new PhutilClassMapQuery())
|
||||
->setAncestorClass(__CLASS__)
|
||||
->setUniqueMethod('getExtensionKey')
|
||||
->setSortMethod('getExtensionOrder')
|
||||
->execute();
|
||||
}
|
||||
|
||||
|
|
|
@ -82,20 +82,6 @@ final class PhabricatorMainMenuView extends AphrontView {
|
|||
phutil_implode_html(' ', $aural));
|
||||
}
|
||||
|
||||
// Build out Header Menus
|
||||
$applications = PhabricatorApplication::getAllInstalledApplications();
|
||||
|
||||
$menus = array();
|
||||
$controller = $this->getController();
|
||||
foreach ($applications as $application) {
|
||||
$app_extra = $application->buildMainMenuExtraNodes(
|
||||
$viewer,
|
||||
$controller);
|
||||
if ($app_extra !== null) {
|
||||
$menus[] = $app_extra;
|
||||
}
|
||||
}
|
||||
|
||||
$extensions = PhabricatorMainMenuBarExtension::getAllEnabledExtensions();
|
||||
foreach ($extensions as $extension) {
|
||||
$extension->setViewer($viewer);
|
||||
|
@ -116,13 +102,18 @@ final class PhabricatorMainMenuView extends AphrontView {
|
|||
}
|
||||
}
|
||||
|
||||
// Builds out "login" button
|
||||
$menus = array();
|
||||
foreach ($extensions as $extension) {
|
||||
foreach ($extension->buildMainMenus() as $menu) {
|
||||
$menus[] = $menu;
|
||||
}
|
||||
}
|
||||
|
||||
// Because we display these with "float: right", reverse their order before
|
||||
// rendering them into the document so that the extension order and display
|
||||
// order are the same.
|
||||
$menus = array_reverse($menus);
|
||||
|
||||
foreach ($menus as $menu) {
|
||||
$menu_bar[] = $menu;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue