diff --git a/core/config.class.inc.php b/core/config.class.inc.php index de9912033..50a6a0798 100644 --- a/core/config.class.inc.php +++ b/core/config.class.inc.php @@ -1265,6 +1265,14 @@ class Config 'source_of_value' => '', 'show_in_conf_sample' => false, ], + 'navigation_menu.sorted_popup_user_menu_items' => [ + 'type' => 'array', + 'description' => 'Sort user menu items after setup on page load', + 'default' => [], + 'value' => false, + 'source_of_value' => '', + 'show_in_conf_sample' => false, + ], 'quick_create.enabled' => [ 'type' => 'bool', 'description' => 'Whether or not the quick create is enabled', diff --git a/sources/application/UI/Base/Component/PopoverMenu/PopoverMenuFactory.php b/sources/application/UI/Base/Component/PopoverMenu/PopoverMenuFactory.php index 6bb2b0ed9..e358708b9 100644 --- a/sources/application/UI/Base/Component/PopoverMenu/PopoverMenuFactory.php +++ b/sources/application/UI/Base/Component/PopoverMenu/PopoverMenuFactory.php @@ -21,13 +21,14 @@ namespace Combodo\iTop\Application\UI\Base\Component\PopoverMenu; +use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenuItem\PopoverMenuItem; use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenuItem\PopoverMenuItemFactory; use Dict; +use iPopupMenuExtension; use JSPopupMenuItem; use MetaModel; use SeparatorPopupMenuItem; use URLPopupMenuItem; -use iPopupMenuExtension; use UserRights; use utils; @@ -56,30 +57,68 @@ class PopoverMenuFactory ->SetHorizontalPosition(PopoverMenu::ENUM_HORIZONTAL_POSITION_ALIGN_OUTER_RIGHT) ->SetVerticalPosition(PopoverMenu::ENUM_VERTICAL_POSITION_ABOVE); + $aUserMenuItems = []; + // Allowed portals $aAllowedPortalsItems = static::PrepareAllowedPortalsItemsForUserMenu(); - if (!empty($aAllowedPortalsItems)) { - $oMenu->AddSection('allowed_portals') - ->SetItems('allowed_portals', $aAllowedPortalsItems); - } + self::AddPopoverMenuItems($aAllowedPortalsItems, $aUserMenuItems); // User related pages - $oMenu->AddSection('user_related') - ->SetItems('user_related', static::PrepareUserRelatedItemsForUserMenu()); + self::AddPopoverMenuItems(static::PrepareUserRelatedItemsForUserMenu(), $aUserMenuItems); // API: iPopupMenuExtension::MENU_USER_ACTIONS $aAPIItems = static::PrepareAPIItemsForUserMenu($oMenu); - if (count($aAPIItems) > 0) { - $oMenu->AddSection('popup_menu_extension-menu_user_actions') - ->SetItems('popup_menu_extension-menu_user_actions', $aAPIItems); - } + self::AddPopoverMenuItems($aAPIItems, $aUserMenuItems); // Misc links - $oMenu->AddSection('misc') - ->SetItems('misc', static::PrepareMiscItemsForUserMenu()); + /*$oMenu->AddSection('misc') + ->SetItems('misc', static::PrepareMiscItemsForUserMenu());*/ + self::AddPopoverMenuItems(static::PrepareMiscItemsForUserMenu(), $aUserMenuItems); + self::SortPopoverMenuItems($aUserMenuItems); + + $oMenu->AddSection('misc') + ->AddItems('misc', $aUserMenuItems); return $oMenu; } + + /** + * @param PopoverMenuItem[] $aPopoverMenuItem + * @param PopoverMenuItem[] $aUserMenuItems + * + * @return void + */ + private static function AddPopoverMenuItems(array $aPopoverMenuItem, array &$aUserMenuItems) : void { + foreach ($aPopoverMenuItem as $oPopoverMenuItem){ + $aUserMenuItems[$oPopoverMenuItem->GetUID()] = $oPopoverMenuItem; + } + } + + /** + * @param PopoverMenuItem[] $aPopoverMenuItem + * @param PopoverMenuItem[] $aUserMenuItems + * + * @return void + */ + private static function SortPopoverMenuItems(array &$aUserMenuItems) : void { + $aSortedMenusFromConfig = MetaModel::GetConfig()->Get('navigation_menu.sorted_popup_user_menu_items'); + if (!is_array($aSortedMenusFromConfig) || empty($aSortedMenusFromConfig)){ + return; + } + + $aSortedMenus = []; + foreach ($aSortedMenusFromConfig as $sMenuUID){ + if (array_key_exists($sMenuUID, $aUserMenuItems)){ + $aSortedMenus[]=$aUserMenuItems[$sMenuUID]; + unset($aUserMenuItems[$sMenuUID]); + } + } + + foreach ($aUserMenuItems as $oMenu){ + $aSortedMenus[]=$oMenu; + } + $aUserMenuItems = $aSortedMenus; + } /** * Return the allowed portals items for the current user @@ -273,4 +312,4 @@ class PopoverMenuFactory return $oMenu; } -} \ No newline at end of file +} diff --git a/tests/php-unit-tests/unitary-tests/application/UI/Base/Component/PopoverMenu/PopoverMenuFactoryTest.php b/tests/php-unit-tests/unitary-tests/application/UI/Base/Component/PopoverMenu/PopoverMenuFactoryTest.php new file mode 100644 index 000000000..5072c2aa3 --- /dev/null +++ b/tests/php-unit-tests/unitary-tests/application/UI/Base/Component/PopoverMenu/PopoverMenuFactoryTest.php @@ -0,0 +1,96 @@ + [ + 'aConf' => null, + 'aExpectedMenuUIDs' => $aNotSortedMenuUIDs + ], + 'not an array conf' => [ + 'aConf' => "wrong conf", + 'aExpectedMenuUIDs' => $aNotSortedMenuUIDs + ], + 'default conf' => [ + 'aConf' => [], + 'aExpectedMenuUIDs' => $aNotSortedMenuUIDs + ], + 'same order in conf' => [ + 'aConf' => [ + 'portal:itop-portal', + 'UI:Preferences', + 'UI:Help', + 'UI:AboutBox', + ], + 'aExpectedMenuUIDs' => $aNotSortedMenuUIDs + ], + 'first menus sorted and last one missing in conf' => [ + 'aConf' => [ + "portal:itop-portal", + "UI:Preferences", + ], + 'aExpectedMenuUIDs' => $aNotSortedMenuUIDs + ], + 'some menus but not all sorted' => [ + 'aConf' => [ + 'UI:Preferences', + 'UI:AboutBox', + ], + 'aExpectedMenuUIDs' => [ + 'UI_Preferences', + 'UI_AboutBox', + 'portal_itop_portal', + 'UI_Help', + ] + ], + 'all user menu sorted' => [ + 'aConf' => [ + 'UI:Preferences', + 'UI:AboutBox', + 'portal:itop-portal', + 'UI:Help', + ], + 'aExpectedMenuUIDs' => [ + 'UI_Preferences', + 'UI_AboutBox', + 'portal_itop_portal', + 'UI_Help', + ] + ], + ]; + } + /** + * @dataProvider MakeUserMenuForNavigationMenuProvider + */ + public function testMakeUserMenuForNavigationMenu($aConf, $aExpectedMenuUIDs){ + if (! is_null($aConf)){ + \MetaModel::GetConfig()->Set('navigation_menu.sorted_popup_user_menu_items', $aConf); + } + + $aRes = PopoverMenuFactory::MakeUserMenuForNavigationMenu()->GetSections(); + $this->assertTrue(array_key_exists('misc', $aRes)); + $aUIDsWithDummyRandoString = array_keys($aRes['misc']['aItems']); + //replace ibo-popover-menu--item-6464cdca5ecf4214716943--UI_AboutBox by UI_AboutBox (for ex) + $aUIDs = preg_replace('/ibo-popover-menu--item-([^\-]+)--/', '', $aUIDsWithDummyRandoString); + $this->assertEquals($aExpectedMenuUIDs, $aUIDs); + } +}