1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 08:52:39 +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:
epriestley 2017-01-21 08:11:19 -08:00
parent ddf82a815b
commit 402b6473d8
9 changed files with 231 additions and 220 deletions

View file

@ -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',

View file

@ -9,6 +9,10 @@ final class PhabricatorAuthMainMenuBarExtension
return true;
}
public function getExtensionOrder() {
return 900;
}
public function buildMainMenus() {
$viewer = $this->getViewer();

View file

@ -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 )--------------------------------------------- */

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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();
}

View file

@ -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;
}