diff --git a/application/menunode.class.inc.php b/application/menunode.class.inc.php index 91bb17028..1bcbe3ce3 100644 --- a/application/menunode.class.inc.php +++ b/application/menunode.class.inc.php @@ -225,11 +225,12 @@ class ApplicationMenu } $sMenuGroupIdx = $aMenuGroup['index']; + /** @var \MenuGroup $oMenuNode */ $oMenuNode = static::GetMenuNode($sMenuGroupIdx); $aMenuGroups[] = [ 'sId' => $oMenuNode->GetMenuID(), - 'sIconCssClasses' => 'fas fa-fw fa-home', // TODO: Get the classes from the datamodel + 'sIconCssClasses' => $oMenuNode->GetDecorationClasses(), 'sTitle' => $oMenuNode->GetTitle(), 'aSubMenuNodes' => static::GetSubMenuNodes($sMenuGroupIdx, $aExtraParams), ]; @@ -822,18 +823,42 @@ abstract class MenuNode */ class MenuGroup extends MenuNode { + /** @var string DEFAULT_DECORATION_CLASSES */ + const DEFAULT_DECORATION_CLASSES = 'fas fa-ellipsis-v'; + + /** @var string The CSS classes used to display the menu group's icon */ + protected $sDecorationClasses = self::DEFAULT_DECORATION_CLASSES; + /** * Create a top-level menu group and inserts it into the application's main menu + * * @param string $sMenuId Unique identifier of the menu (used to identify the menu for bookmarking, and for getting the labels from the dictionary) * @param float $fRank Number used to order the list, the groups are sorted based on this value + * @param string|null $sDecorationClasses CSS classes used to display the menu group's icon * @param string $sEnableClass Name of class of object * @param integer $iActionCode Either UR_ACTION_READ, UR_ACTION_MODIFY, UR_ACTION_DELETE, UR_ACTION_BULKREAD, UR_ACTION_BULKMODIFY or UR_ACTION_BULKDELETE * @param integer $iAllowedResults Expected "rights" for the action: either UR_ALLOWED_YES, UR_ALLOWED_NO, UR_ALLOWED_DEPENDS or a mix of them... * @param string $sEnableStimulus */ - public function __construct($sMenuId, $fRank, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null) + public function __construct($sMenuId, $fRank, $sDecorationClasses = null, $sEnableClass = null, $iActionCode = null, $iAllowedResults = UR_ALLOWED_YES, $sEnableStimulus = null) { parent::__construct($sMenuId, -1 /* no parent, groups are at root level */, $fRank, $sEnableClass, $iActionCode, $iAllowedResults, $sEnableStimulus); + + if(!empty($sDecorationClasses)) + { + $this->sDecorationClasses = $sDecorationClasses; + } + } + + /** + * Return the CSS classes used for decorating the menu group (typically the icon in the navigation menu) + * + * @return string + * @since 2.8.0 + */ + public function GetDecorationClasses() + { + return $this->sDecorationClasses; } /** diff --git a/setup/compiler.class.inc.php b/setup/compiler.class.inc.php index 30f339d80..6a2d3c557 100644 --- a/setup/compiler.class.inc.php +++ b/setup/compiler.class.inc.php @@ -2179,6 +2179,13 @@ EOF break; case 'MenuGroup': + $oStyleNode = $oMenu->GetOptionalElement('style'); + // Note: We use '' as the default value to ease the MenuGroup::__construct() call as we would have to make a different processing to not put the quotes around the parameter in case of null. + $sDecorationClasses = ($oStyleNode === null) ? '' : $oStyleNode->GetChildText('decoration_classes', ''); + + $sNewMenu = "new MenuGroup('$sMenuId', $fRank, '$sDecorationClasses' {$sOptionalEnableParams});"; + break; + default: $sNewMenu = "new $sMenuClass('$sMenuId', $fRank {$sOptionalEnableParams});"; } diff --git a/setup/itopdesignformat.class.inc.php b/setup/itopdesignformat.class.inc.php index 0e2c77873..37a8c9618 100644 --- a/setup/itopdesignformat.class.inc.php +++ b/setup/itopdesignformat.class.inc.php @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License */ -define('ITOP_DESIGN_LATEST_VERSION', '1.7'); // iTop >= 2.7.0 +define('ITOP_DESIGN_LATEST_VERSION', '1.8'); // iTop >= 2.8.0 /** * Utility to upgrade the format of a given XML datamodel to the latest version @@ -87,6 +87,12 @@ class iTopDesignFormat '1.7' => array( 'previous' => '1.6', 'go_to_previous' => 'From17To16', + 'next' => '1.8', + 'go_to_next' => 'From17To18', + ), + '1.8' => array( + 'previous' => '1.7', + 'go_to_previous' => 'From18To17', 'next' => null, 'go_to_next' => null, ), @@ -757,6 +763,28 @@ class iTopDesignFormat $this->RemoveNodeFromXPath($sPath); } + /** + * Upgrade the format from version 1.7 to 1.8 + * @param \ModelFactory $oFactory + * @return void (Errors are logged) + */ + protected function From17To18($oFactory) + { + // Nothing + } + + /** + * Downgrade the format from version 1.8 to 1.7 + * @param \ModelFactory $oFactory + * @return void (Errors are logged) + */ + protected function From18To17($oFactory) + { + // -- 3182 - Remove style node from MenuGroup + $sPath = "/itop_design/menus/menu[@xsi:type='MenuGroup']/style"; + $this->RemoveNodeFromXPath($sPath); + } + /** * @param string $sPath * diff --git a/templates/layouts/navigation-menu/menu-group.html.twig b/templates/layouts/navigation-menu/menu-group.html.twig index bf04f298f..fbb89e464 100644 --- a/templates/layouts/navigation-menu/menu-group.html.twig +++ b/templates/layouts/navigation-menu/menu-group.html.twig @@ -1,4 +1,4 @@ - + {{ aMenuGroup.sTitle }} \ No newline at end of file