1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 00:42:41 +01:00

Begin modularizing main menu items

Summary:
Ref T10077. Ref T8918. The way the main menu is built is not very modular and fairly hacky.

It assumes menus are provided by applications, but this isn't exactly true. Notably, the "Quick Create" menu is not per-application.

The current method of building this menu is very inefficient (see T10077). Particularly, we have to build it //twice// because we need to build it once to render the item and then again to render the dropdown options.

Start cleaning this up. This diff doesn't actually have any behavioral changes, since I can't swap the menu over until we get rid of all the other items and I haven't extended this to Notifications/Conpherence yet so it doesn't actually fix T8918.

Test Plan: Viewed menus while logged in, logged out, in different applications, in desktop/mobile. Nothing appeared different.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T8918, T10077

Differential Revision: https://secure.phabricator.com/D14922
This commit is contained in:
epriestley 2016-01-01 04:26:36 -08:00
parent bcfd6bdd81
commit 08de131da5
12 changed files with 418 additions and 209 deletions

View file

@ -1500,6 +1500,7 @@ phutil_register_library_map(array(
'PHUIListItemView' => 'view/phui/PHUIListItemView.php', 'PHUIListItemView' => 'view/phui/PHUIListItemView.php',
'PHUIListView' => 'view/phui/PHUIListView.php', 'PHUIListView' => 'view/phui/PHUIListView.php',
'PHUIListViewTestCase' => 'view/layout/__tests__/PHUIListViewTestCase.php', 'PHUIListViewTestCase' => 'view/layout/__tests__/PHUIListViewTestCase.php',
'PHUIMainMenuView' => 'view/phui/PHUIMainMenuView.php',
'PHUIObjectBoxView' => 'view/phui/PHUIObjectBoxView.php', 'PHUIObjectBoxView' => 'view/phui/PHUIObjectBoxView.php',
'PHUIObjectItemListExample' => 'applications/uiexample/examples/PHUIObjectItemListExample.php', 'PHUIObjectItemListExample' => 'applications/uiexample/examples/PHUIObjectItemListExample.php',
'PHUIObjectItemListView' => 'view/phui/PHUIObjectItemListView.php', 'PHUIObjectItemListView' => 'view/phui/PHUIObjectItemListView.php',
@ -1722,6 +1723,7 @@ phutil_register_library_map(array(
'PhabricatorAuthListController' => 'applications/auth/controller/config/PhabricatorAuthListController.php', 'PhabricatorAuthListController' => 'applications/auth/controller/config/PhabricatorAuthListController.php',
'PhabricatorAuthLoginController' => 'applications/auth/controller/PhabricatorAuthLoginController.php', 'PhabricatorAuthLoginController' => 'applications/auth/controller/PhabricatorAuthLoginController.php',
'PhabricatorAuthLoginHandler' => 'applications/auth/handler/PhabricatorAuthLoginHandler.php', 'PhabricatorAuthLoginHandler' => 'applications/auth/handler/PhabricatorAuthLoginHandler.php',
'PhabricatorAuthMainMenuBarExtension' => 'applications/auth/extension/PhabricatorAuthMainMenuBarExtension.php',
'PhabricatorAuthManagementCachePKCS8Workflow' => 'applications/auth/management/PhabricatorAuthManagementCachePKCS8Workflow.php', 'PhabricatorAuthManagementCachePKCS8Workflow' => 'applications/auth/management/PhabricatorAuthManagementCachePKCS8Workflow.php',
'PhabricatorAuthManagementLDAPWorkflow' => 'applications/auth/management/PhabricatorAuthManagementLDAPWorkflow.php', 'PhabricatorAuthManagementLDAPWorkflow' => 'applications/auth/management/PhabricatorAuthManagementLDAPWorkflow.php',
'PhabricatorAuthManagementListFactorsWorkflow' => 'applications/auth/management/PhabricatorAuthManagementListFactorsWorkflow.php', 'PhabricatorAuthManagementListFactorsWorkflow' => 'applications/auth/management/PhabricatorAuthManagementListFactorsWorkflow.php',
@ -2363,6 +2365,7 @@ phutil_register_library_map(array(
'PhabricatorHelpDocumentationController' => 'applications/help/controller/PhabricatorHelpDocumentationController.php', 'PhabricatorHelpDocumentationController' => 'applications/help/controller/PhabricatorHelpDocumentationController.php',
'PhabricatorHelpEditorProtocolController' => 'applications/help/controller/PhabricatorHelpEditorProtocolController.php', 'PhabricatorHelpEditorProtocolController' => 'applications/help/controller/PhabricatorHelpEditorProtocolController.php',
'PhabricatorHelpKeyboardShortcutController' => 'applications/help/controller/PhabricatorHelpKeyboardShortcutController.php', 'PhabricatorHelpKeyboardShortcutController' => 'applications/help/controller/PhabricatorHelpKeyboardShortcutController.php',
'PhabricatorHelpMainMenuBarExtension' => 'applications/help/extension/PhabricatorHelpMainMenuBarExtension.php',
'PhabricatorHeraldApplication' => 'applications/herald/application/PhabricatorHeraldApplication.php', 'PhabricatorHeraldApplication' => 'applications/herald/application/PhabricatorHeraldApplication.php',
'PhabricatorHighSecurityRequestExceptionHandler' => 'aphront/handler/PhabricatorHighSecurityRequestExceptionHandler.php', 'PhabricatorHighSecurityRequestExceptionHandler' => 'aphront/handler/PhabricatorHighSecurityRequestExceptionHandler.php',
'PhabricatorHomeApplication' => 'applications/home/application/PhabricatorHomeApplication.php', 'PhabricatorHomeApplication' => 'applications/home/application/PhabricatorHomeApplication.php',
@ -2480,6 +2483,7 @@ phutil_register_library_map(array(
'PhabricatorMailSetupCheck' => 'applications/config/check/PhabricatorMailSetupCheck.php', 'PhabricatorMailSetupCheck' => 'applications/config/check/PhabricatorMailSetupCheck.php',
'PhabricatorMailTarget' => 'applications/metamta/replyhandler/PhabricatorMailTarget.php', 'PhabricatorMailTarget' => 'applications/metamta/replyhandler/PhabricatorMailTarget.php',
'PhabricatorMailgunConfigOptions' => 'applications/config/option/PhabricatorMailgunConfigOptions.php', 'PhabricatorMailgunConfigOptions' => 'applications/config/option/PhabricatorMailgunConfigOptions.php',
'PhabricatorMainMenuBarExtension' => 'view/page/menu/PhabricatorMainMenuBarExtension.php',
'PhabricatorMainMenuSearchView' => 'view/page/menu/PhabricatorMainMenuSearchView.php', 'PhabricatorMainMenuSearchView' => 'view/page/menu/PhabricatorMainMenuSearchView.php',
'PhabricatorMainMenuView' => 'view/page/menu/PhabricatorMainMenuView.php', 'PhabricatorMainMenuView' => 'view/page/menu/PhabricatorMainMenuView.php',
'PhabricatorManagementWorkflow' => 'infrastructure/management/PhabricatorManagementWorkflow.php', 'PhabricatorManagementWorkflow' => 'infrastructure/management/PhabricatorManagementWorkflow.php',
@ -2724,6 +2728,7 @@ phutil_register_library_map(array(
'PhabricatorPeopleLogQuery' => 'applications/people/query/PhabricatorPeopleLogQuery.php', 'PhabricatorPeopleLogQuery' => 'applications/people/query/PhabricatorPeopleLogQuery.php',
'PhabricatorPeopleLogSearchEngine' => 'applications/people/query/PhabricatorPeopleLogSearchEngine.php', 'PhabricatorPeopleLogSearchEngine' => 'applications/people/query/PhabricatorPeopleLogSearchEngine.php',
'PhabricatorPeopleLogsController' => 'applications/people/controller/PhabricatorPeopleLogsController.php', 'PhabricatorPeopleLogsController' => 'applications/people/controller/PhabricatorPeopleLogsController.php',
'PhabricatorPeopleMainMenuBarExtension' => 'applications/people/extension/PhabricatorPeopleMainMenuBarExtension.php',
'PhabricatorPeopleNewController' => 'applications/people/controller/PhabricatorPeopleNewController.php', 'PhabricatorPeopleNewController' => 'applications/people/controller/PhabricatorPeopleNewController.php',
'PhabricatorPeopleNoOwnerDatasource' => 'applications/people/typeahead/PhabricatorPeopleNoOwnerDatasource.php', 'PhabricatorPeopleNoOwnerDatasource' => 'applications/people/typeahead/PhabricatorPeopleNoOwnerDatasource.php',
'PhabricatorPeopleOwnerDatasource' => 'applications/people/typeahead/PhabricatorPeopleOwnerDatasource.php', 'PhabricatorPeopleOwnerDatasource' => 'applications/people/typeahead/PhabricatorPeopleOwnerDatasource.php',
@ -3091,6 +3096,7 @@ phutil_register_library_map(array(
'PhabricatorSettingsAdjustController' => 'applications/settings/controller/PhabricatorSettingsAdjustController.php', 'PhabricatorSettingsAdjustController' => 'applications/settings/controller/PhabricatorSettingsAdjustController.php',
'PhabricatorSettingsApplication' => 'applications/settings/application/PhabricatorSettingsApplication.php', 'PhabricatorSettingsApplication' => 'applications/settings/application/PhabricatorSettingsApplication.php',
'PhabricatorSettingsMainController' => 'applications/settings/controller/PhabricatorSettingsMainController.php', 'PhabricatorSettingsMainController' => 'applications/settings/controller/PhabricatorSettingsMainController.php',
'PhabricatorSettingsMainMenuBarExtension' => 'applications/settings/extension/PhabricatorSettingsMainMenuBarExtension.php',
'PhabricatorSettingsPanel' => 'applications/settings/panel/PhabricatorSettingsPanel.php', 'PhabricatorSettingsPanel' => 'applications/settings/panel/PhabricatorSettingsPanel.php',
'PhabricatorSetupCheck' => 'applications/config/check/PhabricatorSetupCheck.php', 'PhabricatorSetupCheck' => 'applications/config/check/PhabricatorSetupCheck.php',
'PhabricatorSetupCheckTestCase' => 'applications/config/check/__tests__/PhabricatorSetupCheckTestCase.php', 'PhabricatorSetupCheckTestCase' => 'applications/config/check/__tests__/PhabricatorSetupCheckTestCase.php',
@ -5615,6 +5621,7 @@ phutil_register_library_map(array(
'PHUIListItemView' => 'AphrontTagView', 'PHUIListItemView' => 'AphrontTagView',
'PHUIListView' => 'AphrontTagView', 'PHUIListView' => 'AphrontTagView',
'PHUIListViewTestCase' => 'PhabricatorTestCase', 'PHUIListViewTestCase' => 'PhabricatorTestCase',
'PHUIMainMenuView' => 'AphrontView',
'PHUIObjectBoxView' => 'AphrontView', 'PHUIObjectBoxView' => 'AphrontView',
'PHUIObjectItemListExample' => 'PhabricatorUIExample', 'PHUIObjectItemListExample' => 'PhabricatorUIExample',
'PHUIObjectItemListView' => 'AphrontTagView', 'PHUIObjectItemListView' => 'AphrontTagView',
@ -5863,6 +5870,7 @@ phutil_register_library_map(array(
'PhabricatorAuthListController' => 'PhabricatorAuthProviderConfigController', 'PhabricatorAuthListController' => 'PhabricatorAuthProviderConfigController',
'PhabricatorAuthLoginController' => 'PhabricatorAuthController', 'PhabricatorAuthLoginController' => 'PhabricatorAuthController',
'PhabricatorAuthLoginHandler' => 'Phobject', 'PhabricatorAuthLoginHandler' => 'Phobject',
'PhabricatorAuthMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension',
'PhabricatorAuthManagementCachePKCS8Workflow' => 'PhabricatorAuthManagementWorkflow', 'PhabricatorAuthManagementCachePKCS8Workflow' => 'PhabricatorAuthManagementWorkflow',
'PhabricatorAuthManagementLDAPWorkflow' => 'PhabricatorAuthManagementWorkflow', 'PhabricatorAuthManagementLDAPWorkflow' => 'PhabricatorAuthManagementWorkflow',
'PhabricatorAuthManagementListFactorsWorkflow' => 'PhabricatorAuthManagementWorkflow', 'PhabricatorAuthManagementListFactorsWorkflow' => 'PhabricatorAuthManagementWorkflow',
@ -6631,6 +6639,7 @@ phutil_register_library_map(array(
'PhabricatorHelpDocumentationController' => 'PhabricatorHelpController', 'PhabricatorHelpDocumentationController' => 'PhabricatorHelpController',
'PhabricatorHelpEditorProtocolController' => 'PhabricatorHelpController', 'PhabricatorHelpEditorProtocolController' => 'PhabricatorHelpController',
'PhabricatorHelpKeyboardShortcutController' => 'PhabricatorHelpController', 'PhabricatorHelpKeyboardShortcutController' => 'PhabricatorHelpController',
'PhabricatorHelpMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension',
'PhabricatorHeraldApplication' => 'PhabricatorApplication', 'PhabricatorHeraldApplication' => 'PhabricatorApplication',
'PhabricatorHighSecurityRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler', 'PhabricatorHighSecurityRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler',
'PhabricatorHomeApplication' => 'PhabricatorApplication', 'PhabricatorHomeApplication' => 'PhabricatorApplication',
@ -6748,6 +6757,7 @@ phutil_register_library_map(array(
'PhabricatorMailSetupCheck' => 'PhabricatorSetupCheck', 'PhabricatorMailSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorMailTarget' => 'Phobject', 'PhabricatorMailTarget' => 'Phobject',
'PhabricatorMailgunConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorMailgunConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorMainMenuBarExtension' => 'Phobject',
'PhabricatorMainMenuSearchView' => 'AphrontView', 'PhabricatorMainMenuSearchView' => 'AphrontView',
'PhabricatorMainMenuView' => 'AphrontView', 'PhabricatorMainMenuView' => 'AphrontView',
'PhabricatorManagementWorkflow' => 'PhutilArgumentWorkflow', 'PhabricatorManagementWorkflow' => 'PhutilArgumentWorkflow',
@ -7037,6 +7047,7 @@ phutil_register_library_map(array(
'PhabricatorPeopleLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorPeopleLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorPeopleLogSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhabricatorPeopleLogSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorPeopleLogsController' => 'PhabricatorPeopleController', 'PhabricatorPeopleLogsController' => 'PhabricatorPeopleController',
'PhabricatorPeopleMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension',
'PhabricatorPeopleNewController' => 'PhabricatorPeopleController', 'PhabricatorPeopleNewController' => 'PhabricatorPeopleController',
'PhabricatorPeopleNoOwnerDatasource' => 'PhabricatorTypeaheadDatasource', 'PhabricatorPeopleNoOwnerDatasource' => 'PhabricatorTypeaheadDatasource',
'PhabricatorPeopleOwnerDatasource' => 'PhabricatorTypeaheadCompositeDatasource', 'PhabricatorPeopleOwnerDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
@ -7488,6 +7499,7 @@ phutil_register_library_map(array(
'PhabricatorSettingsAdjustController' => 'PhabricatorController', 'PhabricatorSettingsAdjustController' => 'PhabricatorController',
'PhabricatorSettingsApplication' => 'PhabricatorApplication', 'PhabricatorSettingsApplication' => 'PhabricatorApplication',
'PhabricatorSettingsMainController' => 'PhabricatorController', 'PhabricatorSettingsMainController' => 'PhabricatorController',
'PhabricatorSettingsMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension',
'PhabricatorSettingsPanel' => 'Phobject', 'PhabricatorSettingsPanel' => 'Phobject',
'PhabricatorSetupCheck' => 'Phobject', 'PhabricatorSetupCheck' => 'Phobject',
'PhabricatorSetupCheckTestCase' => 'PhabricatorTestCase', 'PhabricatorSetupCheckTestCase' => 'PhabricatorTestCase',

View file

@ -38,48 +38,6 @@ final class PhabricatorAuthApplication extends PhabricatorApplication {
return array(); return array();
} }
public function buildMainMenuItems(
PhabricatorUser $user,
PhabricatorController $controller = null) {
$items = array();
if ($user->isLoggedIn()) {
$item = id(new PHUIListItemView())
->addClass('core-menu-item')
->setName(pht('Log Out'))
->setIcon('fa-sign-out')
->setWorkflow(true)
->setHref('/logout/')
->setSelected(($controller instanceof PhabricatorLogoutController))
->setAural(pht('Log Out'))
->setOrder(900);
$items[] = $item;
} else {
if ($controller instanceof PhabricatorAuthController) {
// Don't show the "Login" item on auth controllers, since they're
// generally all related to logging in anyway.
} else {
$uri = new PhutilURI('/auth/start/');
if ($controller) {
$path = $controller->getRequest()->getPath();
$uri->setQueryParam('next', $path);
}
$item = id(new PHUIListItemView())
->addClass('core-menu-item')
->setName(pht('Log In'))
// TODO: Login icon?
->setIcon('fa-sign-in')
->setHref($uri)
->setAural(pht('Log In'))
->setOrder(900);
$items[] = $item;
}
}
return $items;
}
public function getApplicationGroup() { public function getApplicationGroup() {
return self::GROUP_ADMIN; return self::GROUP_ADMIN;
} }

View file

@ -0,0 +1,73 @@
<?php
final class PhabricatorAuthMainMenuBarExtension
extends PhabricatorMainMenuBarExtension {
const MAINMENUBARKEY = 'auth';
public function isExtensionEnabledForViewer(PhabricatorUser $viewer) {
return true;
}
public function buildMainMenus() {
$viewer = $this->getViewer();
if ($viewer->isLoggedIn()) {
return array(
$this->buildLogoutMenu(),
);
}
$controller = $this->getController();
if ($controller instanceof PhabricatorAuthController) {
// Don't show the "Login" item on auth controllers, since they're
// generally all related to logging in anyway.
return array();
}
return array(
$this->buildLoginMenu(),
);
}
private function buildLogoutMenu() {
$controller = $this->getController();
$is_selected = ($controller instanceof PhabricatorLogoutController);
$bar_item = id(new PHUIListItemView())
->addClass('core-menu-item')
->setName(pht('Log Out'))
->setIcon('fa-sign-out')
->setWorkflow(true)
->setHref('/logout/')
->setSelected($is_selected)
->setAural(pht('Log Out'));
return id(new PHUIMainMenuView())
->setOrder(900)
->setMenuBarItem($bar_item);
}
private function buildLoginMenu() {
$controller = $this->getController();
$uri = new PhutilURI('/auth/start/');
if ($controller) {
$path = $controller->getRequest()->getPath();
$uri->setQueryParam('next', $path);
}
$bar_item = id(new PHUIListItemView())
->addClass('core-menu-item')
->setName(pht('Log In'))
->setIcon('fa-sign-in')
->setHref($uri)
->setAural(pht('Log In'));
return id(new PHUIMainMenuView())
->setOrder(900)
->setMenuBarItem($bar_item);
}
}

View file

@ -25,84 +25,4 @@ final class PhabricatorHelpApplication extends PhabricatorApplication {
); );
} }
public function buildMainMenuItems(
PhabricatorUser $user,
PhabricatorController $controller = null) {
$application = null;
if ($controller) {
$application = $controller->getCurrentApplication();
}
$items = array();
$help_id = celerity_generate_unique_node_id();
Javelin::initBehavior(
'aphlict-dropdown',
array(
'bubbleID' => $help_id,
'dropdownID' => 'phabricator-help-menu',
'applicationClass' => __CLASS__,
'local' => true,
'desktop' => true,
'right' => true,
));
$item = id(new PHUIListItemView())
->setIcon('fa-life-ring')
->addClass('core-menu-item')
->setID($help_id)
->setOrder(200);
$hide = true;
if ($application) {
$help_name = pht('%s Help', $application->getName());
$item
->setName($help_name)
->setHref('/help/documentation/'.get_class($application).'/')
->setAural($help_name);
$help_items = $application->getHelpMenuItems($user);
if ($help_items) {
$hide = false;
}
}
if ($hide) {
$item->setStyle('display: none');
}
$items[] = $item;
return $items;
}
public function buildMainMenuExtraNodes(
PhabricatorUser $viewer,
PhabricatorController $controller = null) {
$application = null;
if ($controller) {
$application = $controller->getCurrentApplication();
}
$view = null;
if ($application) {
$help_items = $application->getHelpMenuItems($viewer);
if ($help_items) {
$view = new PHUIListView();
foreach ($help_items as $item) {
$view->addMenuItem($item);
}
}
}
return phutil_tag(
'div',
array(
'id' => 'phabricator-help-menu',
'class' => 'phabricator-main-menu-dropdown phui-list-sidenav',
'style' => 'display: none',
),
$view);
}
} }

View file

@ -0,0 +1,70 @@
<?php
final class PhabricatorHelpMainMenuBarExtension
extends PhabricatorMainMenuBarExtension {
const MAINMENUBARKEY = 'help';
public function isExtensionEnabledForViewer(PhabricatorUser $viewer) {
return true;
}
public function buildMainMenus() {
$application = $this->getApplication();
if (!$application) {
return array();
}
$viewer = $this->getViewer();
$help_links = $application->getHelpMenuItems($viewer);
if (!$help_links) {
return array();
}
$help_id = celerity_generate_unique_node_id();
Javelin::initBehavior(
'aphlict-dropdown',
array(
'bubbleID' => $help_id,
'dropdownID' => 'phabricator-help-menu',
'local' => true,
'desktop' => true,
'right' => true,
));
$help_name = pht('%s Help', $application->getName());
$help_item = id(new PHUIListItemView())
->setIcon('fa-life-ring')
->addClass('core-menu-item')
->setID($help_id)
->setName($help_name)
->setHref('/help/documentation/'.get_class($application).'/')
->setAural($help_name);
$view = new PHUIListView();
foreach ($help_links as $help_link) {
$view->addMenuItem($help_link);
}
$dropdown_menu = phutil_tag(
'div',
array(
'id' => 'phabricator-help-menu',
'class' => 'phabricator-main-menu-dropdown phui-list-sidenav',
'style' => 'display: none',
),
$view);
$help_menu = id(new PHUIMainMenuView())
->setOrder(200)
->setMenuBarItem($help_item)
->appendChild($dropdown_menu);
return array(
$help_menu,
);
}
}

View file

@ -123,48 +123,6 @@ final class PhabricatorPeopleApplication extends PhabricatorApplication {
return $status; return $status;
} }
public function buildMainMenuItems(
PhabricatorUser $user,
PhabricatorController $controller = null) {
$items = array();
if ($user->isLoggedIn() && $user->isUserActivated()) {
$profile = id(new PhabricatorPeopleQuery())
->setViewer($user)
->needProfileImage(true)
->withPHIDs(array($user->getPHID()))
->executeOne();
$image = $profile->getProfileImageURI();
$item = id(new PHUIListItemView())
->setName($user->getUsername())
->setHref('/p/'.$user->getUsername().'/')
->addClass('core-menu-item')
->setAural(pht('Profile'))
->setOrder(100);
$classes = array(
'phabricator-core-menu-icon',
'phabricator-core-menu-profile-image',
);
$item->appendChild(
phutil_tag(
'span',
array(
'class' => implode(' ', $classes),
'style' => 'background-image: url('.$image.')',
),
''));
$items[] = $item;
}
return $items;
}
public function getQuickCreateItems(PhabricatorUser $viewer) { public function getQuickCreateItems(PhabricatorUser $viewer) {
$items = array(); $items = array();

View file

@ -0,0 +1,49 @@
<?php
final class PhabricatorPeopleMainMenuBarExtension
extends PhabricatorMainMenuBarExtension {
const MAINMENUBARKEY = 'people';
public function buildMainMenus() {
$viewer = $this->getViewer();
// TODO: This should get cached.
$profile = id(new PhabricatorPeopleQuery())
->setViewer($viewer)
->needProfileImage(true)
->withPHIDs(array($viewer->getPHID()))
->executeOne();
$image = $profile->getProfileImageURI();
$bar_item = id(new PHUIListItemView())
->setName($viewer->getUsername())
->setHref('/p/'.$viewer->getUsername().'/')
->addClass('core-menu-item')
->setAural(pht('Profile'));
$classes = array(
'phabricator-core-menu-icon',
'phabricator-core-menu-profile-image',
);
$bar_item->appendChild(
phutil_tag(
'span',
array(
'class' => implode(' ', $classes),
'style' => 'background-image: url('.$image.')',
),
''));
$profile_menu = id(new PHUIMainMenuView())
->setOrder(100)
->setMenuBarItem($bar_item);
return array(
$profile_menu,
);
}
}

View file

@ -40,26 +40,4 @@ final class PhabricatorSettingsApplication extends PhabricatorApplication {
return self::GROUP_UTILITIES; return self::GROUP_UTILITIES;
} }
public function buildMainMenuItems(
PhabricatorUser $user,
PhabricatorController $controller = null) {
$items = array();
if ($user->isLoggedIn() && $user->isUserActivated()) {
$selected = ($controller instanceof PhabricatorSettingsMainController);
$item = id(new PHUIListItemView())
->setName(pht('Settings'))
->setIcon('fa-wrench')
->addClass('core-menu-item')
->setSelected($selected)
->setHref('/settings/')
->setAural(pht('Settings'))
->setOrder(400);
$items[] = $item;
}
return $items;
}
} }

View file

@ -0,0 +1,29 @@
<?php
final class PhabricatorSettingsMainMenuBarExtension
extends PhabricatorMainMenuBarExtension {
const MAINMENUBARKEY = 'settings';
public function buildMainMenus() {
$controller = $this->getController();
$is_selected = ($controller instanceof PhabricatorSettingsMainController);
$bar_item = id(new PHUIListItemView())
->setName(pht('Settings'))
->setIcon('fa-wrench')
->addClass('core-menu-item')
->setSelected($is_selected)
->setHref('/settings/')
->setAural(pht('Settings'));
$settings_menu = id(new PHUIMainMenuView())
->setMenuBarItem($bar_item)
->setOrder(400);
return array(
$settings_menu,
);
}
}

View file

@ -0,0 +1,88 @@
<?php
abstract class PhabricatorMainMenuBarExtension extends Phobject {
private $viewer;
private $application;
private $controller;
public function setViewer(PhabricatorUser $viewer) {
$this->viewer = $viewer;
return $this;
}
public function getViewer() {
return $this->viewer;
}
public function setApplication(PhabricatorApplication $application) {
$this->application = $application;
return $this;
}
public function getApplication() {
return $this->application;
}
public function setController(PhabricatorController $controller) {
$this->controller = $controller;
return $this;
}
public function getController() {
return $this->controller;
}
final public function getExtensionKey() {
return $this->getPhobjectClassConstant('MAINMENUBARKEY');
}
public function isExtensionEnabled() {
return true;
}
public function isExtensionEnabledForViewer(PhabricatorUser $viewer) {
if (!$viewer->isLoggedIn()) {
return false;
}
if (!$viewer->isUserActivated()) {
return false;
}
// Don't show menus for users with partial sessions. This usually means
// they have logged in but have not made it through MFA, so we don't want
// to show notification counts, saved queries, etc.
if (!$viewer->hasSession()) {
return false;
}
if ($viewer->getSession()->getIsPartial()) {
return false;
}
return true;
}
abstract public function buildMainMenus();
final public static function getAllExtensions() {
return id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
->setUniqueMethod('getExtensionKey')
->execute();
}
final public static function getAllEnabledExtensions() {
$extensions = self::getAllExtensions();
foreach ($extensions as $key => $extension) {
if (!$extension->isExtensionEnabled()) {
unset($extensions[$key]);
}
}
return $extensions;
}
}

View file

@ -30,7 +30,7 @@ final class PhabricatorMainMenuView extends AphrontView {
require_celerity_resource('sprite-main-header-css'); require_celerity_resource('sprite-main-header-css');
$header_id = celerity_generate_unique_node_id(); $header_id = celerity_generate_unique_node_id();
$menus = array(); $menu_bar = array();
$alerts = array(); $alerts = array();
$search_button = ''; $search_button = '';
$app_button = ''; $app_button = '';
@ -41,7 +41,7 @@ final class PhabricatorMainMenuView extends AphrontView {
if (array_filter($menu)) { if (array_filter($menu)) {
$alerts[] = $menu; $alerts[] = $menu;
} }
$menus = array_merge($menus, $dropdowns); $menu_bar = array_merge($menu_bar, $dropdowns);
$app_button = $this->renderApplicationMenuButton($header_id); $app_button = $this->renderApplicationMenuButton($header_id);
$search_button = $this->renderSearchMenuButton($header_id); $search_button = $this->renderSearchMenuButton($header_id);
} else { } else {
@ -73,13 +73,69 @@ final class PhabricatorMainMenuView extends AphrontView {
} }
$applications = PhabricatorApplication::getAllInstalledApplications(); $applications = PhabricatorApplication::getAllInstalledApplications();
$menus = array();
$controller = $this->getController();
foreach ($applications as $application) { foreach ($applications as $application) {
$menus[] = $application->buildMainMenuExtraNodes( $app_actions = $application->buildMainMenuItems(
$user, $user,
$this->getController()); $controller);
$app_extra = $application->buildMainMenuExtraNodes(
$user,
$controller);
foreach ($app_actions as $action) {
$menus[] = id(new PHUIMainMenuView())
->setMenuBarItem($action)
->setOrder($action->getOrder());
}
if ($app_extra !== null) {
$menus[] = id(new PHUIMainMenuView())
->appendChild($app_extra);
}
} }
$application_menu = $this->renderApplicationMenu(); $extensions = PhabricatorMainMenuBarExtension::getAllEnabledExtensions();
foreach ($extensions as $extension) {
$extension->setViewer($user);
$controller = $this->getController();
if ($controller) {
$extension->setController($controller);
$application = $controller->getCurrentApplication();
if ($application) {
$extension->setApplication($application);
}
}
}
foreach ($extensions as $key => $extension) {
if (!$extension->isExtensionEnabledForViewer($extension->getViewer())) {
unset($extensions[$key]);
}
}
foreach ($extensions as $extension) {
foreach ($extension->buildMainMenus() as $menu) {
$menus[] = $menu;
}
}
$menus = msort($menus, 'getOrder');
$bar_items = array();
foreach ($menus as $menu) {
$menu_bar[] = $menu;
$item = $menu->getMenuBarItem();
if ($item === null) {
continue;
}
$bar_items[] = $item;
}
$application_menu = $this->renderApplicationMenu($bar_items);
$classes = array(); $classes = array();
$classes[] = 'phabricator-main-menu sprite-main-header'; $classes[] = 'phabricator-main-menu sprite-main-header';
$classes[] = 'phabricator-main-menu-background'; $classes[] = 'phabricator-main-menu-background';
@ -98,7 +154,7 @@ final class PhabricatorMainMenuView extends AphrontView {
$aural, $aural,
$application_menu, $application_menu,
$search_menu, $search_menu,
$menus, $menu_bar,
)); ));
} }
@ -174,21 +230,8 @@ final class PhabricatorMainMenuView extends AphrontView {
'')); ''));
} }
public function renderApplicationMenu() { private function renderApplicationMenu(array $bar_items) {
$user = $this->getUser(); $user = $this->getUser();
$controller = $this->getController();
$applications = PhabricatorApplication::getAllInstalledApplications();
$actions = array();
foreach ($applications as $application) {
$app_actions = $application->buildMainMenuItems($user, $controller);
foreach ($app_actions as $action) {
$actions[] = $action;
}
}
$actions = msort($actions, 'getOrder');
$view = $this->getApplicationMenu(); $view = $this->getApplicationMenu();
@ -199,13 +242,13 @@ final class PhabricatorMainMenuView extends AphrontView {
$view->addClass('phabricator-dark-menu'); $view->addClass('phabricator-dark-menu');
$view->addClass('phabricator-application-menu'); $view->addClass('phabricator-application-menu');
if ($actions) { if ($bar_items) {
$view->addMenuItem( $view->addMenuItem(
id(new PHUIListItemView()) id(new PHUIListItemView())
->setType(PHUIListItemView::TYPE_LABEL) ->setType(PHUIListItemView::TYPE_LABEL)
->setName(pht('Actions'))); ->setName(pht('Actions')));
foreach ($actions as $action) { foreach ($bar_items as $bar_item) {
$view->addMenuItem($action); $view->addMenuItem($bar_item);
} }
} }

View file

@ -0,0 +1,31 @@
<?php
final class PHUIMainMenuView extends AphrontView {
private $menuItem;
private $extraContent = array();
private $order;
public function setMenuBarItem(PHUIListItemView $menu_item) {
$this->menuItem = $menu_item;
return $this;
}
public function getMenuBarItem() {
return $this->menuItem;
}
public function setOrder($order) {
$this->order = $order;
return $this;
}
public function getOrder() {
return $this->order;
}
public function render() {
return $this->renderChildren();
}
}