1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-10 23:01:04 +01:00

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
This commit is contained in:
epriestley 2017-01-31 10:48:03 -08:00
parent bd99a2b81e
commit f23bfccc04
20 changed files with 298 additions and 314 deletions

View file

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

View file

@ -596,14 +596,18 @@ abstract class PhabricatorApplication
protected function getProfileMenuRouting($controller) {
$edit_route = $this->getEditRoutePattern();
$mode_route = '(?P<itemEditMode>global|custom)/';
return array(
'(?P<itemAction>view)/(?P<itemID>[^/]+)/' => $controller,
'(?P<itemAction>hide)/(?P<itemID>[^/]+)/' => $controller,
'(?P<itemAction>default)/(?P<itemID>[^/]+)/' => $controller,
'(?P<itemAction>configure)/' => $controller,
'(?P<itemAction>reorder)/' => $controller,
'(?P<itemAction>configure)/'.$mode_route => $controller,
'(?P<itemAction>reorder)/'.$mode_route => $controller,
'(?P<itemAction>edit)/'.$edit_route => $controller,
'(?P<itemAction>new)/(?<itemKey>[^/]+)/'.$edit_route => $controller,
'(?P<itemAction>new)/'.$mode_route.'(?<itemKey>[^/]+)/'.$edit_route
=> $controller,
'(?P<itemAction>builtin)/(?<itemID>[^/]+)/'.$edit_route
=> $controller,
);

View file

@ -21,8 +21,7 @@ final class PhabricatorFavoritesApplication extends PhabricatorApplication {
public function getRoutes() {
return array(
'/favorites/' => array(
'' => 'PhabricatorFavoritesMainController',
'(?P<type>global|personal)/item/' => $this->getProfileMenuRouting(
'menu/' => $this->getProfileMenuRouting(
'PhabricatorFavoritesMenuItemController'),
),
);

View file

@ -1,63 +0,0 @@
<?php
final class PhabricatorFavoritesMainController
extends PhabricatorFavoritesController {
public function shouldAllowPublic() {
return false;
}
public function handleRequest(AphrontRequest $request) {
$viewer = $request->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);
}
}

View file

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

View file

@ -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) {

View file

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

View file

@ -22,14 +22,11 @@ final class PhabricatorHomeApplication extends PhabricatorApplication {
public function getRoutes() {
return array(
'/' => 'PhabricatorHomeMainController',
'/(?P<only>home)/' => 'PhabricatorHomeMainController',
'/' => 'PhabricatorHomeMenuItemController',
'/home/' => array(
'menu/' => array(
'' => 'PhabricatorHomeMenuController',
'(?P<type>global|personal)/item/' => $this->getProfileMenuRouting(
'' => 'PhabricatorHomeMenuItemController',
'menu/' => $this->getProfileMenuRouting(
'PhabricatorHomeMenuItemController'),
),
),
);
}

View file

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

View file

@ -1,62 +0,0 @@
<?php
final class PhabricatorHomeMenuController extends PhabricatorHomeController {
public function shouldAllowPublic() {
return false;
}
public function handleRequest(AphrontRequest $request) {
$viewer = $request->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);
}
}

View file

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

View file

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

View file

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

View file

@ -1,52 +1,23 @@
<?php
final class PhabricatorHomeMainController extends PhabricatorHomeController {
final class PHUIHomeView
extends AphrontTagView {
public function shouldAllowPublic() {
return true;
protected function getTagName() {
return null;
}
public function isGlobalDragAndDropUploadEnabled() {
return true;
protected function getTagAttributes() {
return array();
}
public function handleRequest(AphrontRequest $request) {
$viewer = $request->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() {

View file

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

View file

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

View file

@ -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 {

View file

@ -1,12 +1,12 @@
<?php
final class PhabricatorHomeManageProfileMenuItem
final class PhabricatorManageProfileMenuItem
extends PhabricatorProfileMenuItem {
const MENUITEMKEY = 'home.manage.menu';
const MENUITEMKEY = 'menu.manage';
public function getMenuItemTypeName() {
return pht('Manage Home Menu');
return pht('Manage Menu');
}
private function getDefaultName() {
@ -49,17 +49,21 @@ final class PhabricatorHomeManageProfileMenuItem
PhabricatorProfileMenuItemConfiguration $config) {
$viewer = $this->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,
);

View file

@ -117,6 +117,7 @@ final class PhabricatorProfileMenuItemConfigurationQuery
unset($page[$key]);
continue;
}
$item->attachProfileObject($profile);
}

View file

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