diff --git a/datamodels/2.x/itop-portal-base/portal/src/controllers/browsebrickcontroller.class.inc.php b/datamodels/2.x/itop-portal-base/portal/src/controllers/browsebrickcontroller.class.inc.php index 6f8b7744f..dc15ed258 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/controllers/browsebrickcontroller.class.inc.php +++ b/datamodels/2.x/itop-portal-base/portal/src/controllers/browsebrickcontroller.class.inc.php @@ -446,6 +446,26 @@ class BrowseBrickController extends BrickController } } + // Setting action icon class + if (!isset($aAction['icon_class'])) + { + switch ($aAction['type']) + { + case BrowseBrick::ENUM_ACTION_CREATE_FROM_THIS: + $aAction['icon_class'] = BrowseBrick::ENUM_ACTION_ICON_CLASS_CREATE_FROM_THIS; + break; + case BrowseBrick::ENUM_ACTION_VIEW: + $aAction['icon_class'] = BrowseBrick::ENUM_ACTION_ICON_CLASS_VIEW; + break; + case BrowseBrick::ENUM_ACTION_EDIT: + $aAction['icon_class'] = BrowseBrick::ENUM_ACTION_ICON_CLASS_EDIT; + break; + case BrowseBrick::ENUM_ACTION_DRILLDOWN: + $aAction['icon_class'] = BrowseBrick::ENUM_ACTION_ICON_CLASS_DRILLDOWN; + break; + } + } + // Setting action url switch ($aAction['type']) { diff --git a/datamodels/2.x/itop-portal-base/portal/src/entities/browsebrick.class.inc.php b/datamodels/2.x/itop-portal-base/portal/src/entities/browsebrick.class.inc.php index 9af1c04c4..c35541dd8 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/entities/browsebrick.class.inc.php +++ b/datamodels/2.x/itop-portal-base/portal/src/entities/browsebrick.class.inc.php @@ -36,6 +36,10 @@ class BrowseBrick extends PortalBrick const ENUM_ACTION_EDIT = 'edit'; const ENUM_ACTION_DRILLDOWN = 'drilldown'; const ENUM_ACTION_CREATE_FROM_THIS = 'create_from_this'; + const ENUM_ACTION_ICON_CLASS_VIEW = 'glyphicon glyphicon-list-alt'; + const ENUM_ACTION_ICON_CLASS_EDIT = 'glyphicon glyphicon-pencil'; + const ENUM_ACTION_ICON_CLASS_DRILLDOWN = 'glyphicon glyphicon-menu-down'; + const ENUM_ACTION_ICON_CLASS_CREATE_FROM_THIS = 'glyphicon glyphicon-edit'; const ENUM_FACTORY_TYPE_METHOD = 'method'; const ENUM_FACTORY_TYPE_CLASS = 'class'; const DEFAULT_DATA_LOADING = self::ENUM_DATA_LOADING_FULL; @@ -394,6 +398,12 @@ class BrowseBrick extends PortalBrick { $aTmpAction['title'] = $oActionTitleNode->GetText(); } + // Action icon class + $oActionIconClassNode = $oActionNode->GetOptionalElement('icon_class'); + if ($oActionIconClassNode !== null) + { + $aTmpAction['icon_class'] = $oActionIconClassNode->GetText(); + } // Action rules foreach ($oActionNode->GetNodes('./rules/rule') as $oRuleNode) { diff --git a/datamodels/2.x/itop-portal-base/portal/src/views/bricks/browse/mode_list.html.twig b/datamodels/2.x/itop-portal-base/portal/src/views/bricks/browse/mode_list.html.twig index 2afef278b..bb727b9a1 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/views/bricks/browse/mode_list.html.twig +++ b/datamodels/2.x/itop-portal-base/portal/src/views/bricks/browse/mode_list.html.twig @@ -52,7 +52,7 @@ var drilldownActionIndex; var levelPrimaryAction; var url = ''; - console.log(data, row); + // Preparing actions on the cell levelActions = oLevelsProperties[data.level_alias].actions; // - Removing explicit (not default) drilldown action as it has no prupose on that browse mode @@ -108,48 +108,76 @@ // - Secondary actions if(levelActionsKeys.length > 1) { - var actionsElem = $('
').addClass('pull-right group-actions'); - cellElem.append(actionsElem); - - // Preparing secondary actions for small screens - var actionsSSTogglerElem = $(''); - var actionsSSMenuElem = $(''); - var actionsSSMenuContainerElem = $(''); - actionsSSMenuElem.append(actionsSSMenuContainerElem); - actionsElem.append(actionsSSTogglerElem); - actionsElem.append(actionsSSMenuElem); - + // Retrieving secondary action var actionsButtons = {}; - // Fill actionsButtons with all actions but the primary for(j = 1; j < levelActionsKeys.length; j++) { actionsButtons[levelActionsKeys[j]] = levelActions[levelActionsKeys[j]]; } + + // Preparing secondary actions container + var actionsElem = $('').addClass('pull-right group-actions'); + cellElem.append(actionsElem); + // Checking if a menu is necessary + var bHasSeveralSecondaryActions = (Object.keys(actionsButtons).length > 1); + // Preparing secondary actions for small screens + if(bHasSeveralSecondaryActions) + { + var actionsSSTogglerElem = $(''); + var actionsSSMenuElem = $(''); + var actionsSSMenuContainerElem = $(''); + actionsSSMenuElem.append(actionsSSMenuContainerElem); + actionsElem.append(actionsSSTogglerElem); + actionsElem.append(actionsSSMenuElem); + } + + // Adding secondary actions for(j in actionsButtons) { var action = actionsButtons[j]; var actionElem = $(''); + var actionIconElem = $('').appendTo(actionElem); switch(action.type) { case '{{ constant('Combodo\\iTop\\Portal\\Brick\\BrowseBrick::ENUM_ACTION_VIEW') }}': url = '{{ app.url_generator.generate('p_object_view', {'sObjectClass': '-objectClass-', 'sObjectId': '-objectId-'})|raw }}'.replace(/-objectClass-/, data.class).replace(/-objectId-/, data.id); - actionElem.attr('data-toggle', 'modal').attr('data-target', '#modal-for-all').attr('href', url).text(action.title); + actionElem.attr('data-toggle', 'modal').attr('data-target', '#modal-for-all').attr('href', url); break; case '{{ constant('Combodo\\iTop\\Portal\\Brick\\BrowseBrick::ENUM_ACTION_EDIT') }}': url = '{{ app.url_generator.generate('p_object_edit', {'sObjectClass': '-objectClass-', 'sObjectId': '-objectId-'})|raw }}'.replace(/-objectClass-/, data.class).replace(/-objectId-/, data.id); - actionElem.attr('data-toggle', 'modal').attr('data-target', '#modal-for-all').attr('href', url).text(action.title); + actionElem.attr('data-toggle', 'modal').attr('data-target', '#modal-for-all').attr('href', url); break; case '{{ constant('Combodo\\iTop\\Portal\\Brick\\BrowseBrick::ENUM_ACTION_CREATE_FROM_THIS') }}': url = action.url.replace(/-objectClass-/, data.class).replace(/-objectId-/, data.id); url = addParameterToUrl(url, 'ar_token', data.action_rules_token[action.type]); - actionElem.attr('data-toggle', 'modal').attr('data-target', '#modal-for-all').attr('href', url).text(action.title); + actionElem.attr('data-toggle', 'modal').attr('data-target', '#modal-for-all').attr('href', url); break; default: console.log('Action "'+action.type+'" not implemented for secondary action'); break; } - actionsSSMenuContainerElem.append( $('').append(actionElem.clone()) ); + + // Adding title if present + if(action.title !== undefined) + { + actionElem.attr('title', action.title); + } + // Adding icon class if present + if(action.icon_class !== undefined) + { + actionIconElem.addClass(action.icon_class); + } + + if(bHasSeveralSecondaryActions) + { + actionElem.append(action.title); + actionsSSMenuContainerElem.append( $('').append(actionElem) ); + } + else + { + actionsElem.append(actionElem); + } } } } diff --git a/datamodels/2.x/itop-portal-base/portal/src/views/bricks/browse/mode_tree.html.twig b/datamodels/2.x/itop-portal-base/portal/src/views/bricks/browse/mode_tree.html.twig index 76f695d99..051725dc2 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/views/bricks/browse/mode_tree.html.twig +++ b/datamodels/2.x/itop-portal-base/portal/src/views/bricks/browse/mode_tree.html.twig @@ -233,6 +233,82 @@ if(levelActionsKeys.length > 1) { + // Retrieving secondary action + var actionsButtons = {}; + for(j = 1; j < levelActionsKeys.length; j++) + { + actionsButtons[levelActionsKeys[j]] = levelActions[levelActionsKeys[j]]; + } + + // Preparing secondary actions container + var actionsElem = $('').addClass('list-group-item-actions'); + liElem.append(actionsElem); + // Checking if a menu is necessary + var bHasSeveralSecondaryActions = (Object.keys(actionsButtons).length > 1); + // Preparing secondary actions menu + if(bHasSeveralSecondaryActions) + { + var actionsSSTogglerElem = $(''); + var actionsSSMenuElem = $(''); + var actionsSSMenuContainerElem = $(''); + actionsSSMenuElem.append(actionsSSMenuContainerElem); + actionsElem.append(actionsSSTogglerElem); + actionsElem.append(actionsSSMenuElem); + } + + // Adding secondary actions + for(j in actionsButtons) + { + var action = actionsButtons[j]; + var actionElem = $(''); + var actionIconElem = $('').appendTo(actionElem); + + switch(action.type) + { + case '{{ constant('Combodo\\iTop\\Portal\\Brick\\BrowseBrick::ENUM_ACTION_VIEW') }}': + url = '{{ app.url_generator.generate('p_object_view', {'sObjectClass': '-objectClass-', 'sObjectId': '-objectId-'})|raw }}'.replace(/-objectClass-/, item.class).replace(/-objectId-/, item.id); + actionElem.attr('data-toggle', 'modal').attr('data-target', '#modal-for-all').attr('href', url); + break; + case '{{ constant('Combodo\\iTop\\Portal\\Brick\\BrowseBrick::ENUM_ACTION_EDIT') }}': + url = '{{ app.url_generator.generate('p_object_edit', {'sObjectClass': '-objectClass-', 'sObjectId': '-objectId-'})|raw }}'.replace(/-objectClass-/, item.class).replace(/-objectId-/, item.id); + actionElem.attr('data-toggle', 'modal').attr('data-target', '#modal-for-all').attr('href', url); + break; + case '{{ constant('Combodo\\iTop\\Portal\\Brick\\BrowseBrick::ENUM_ACTION_CREATE_FROM_THIS') }}': + url = action.url.replace(/-objectClass-/, item.class).replace(/-objectId-/, item.id); + url = addParameterToUrl(url, 'ar_token', item.action_rules_token[action.type]); + actionElem.attr('data-toggle', 'modal').attr('data-target', '#modal-for-all').attr('href', url); + break; + default: + console.log('Action "'+action.type+'" not implemented for secondary action'); + break; + } + + // Adding title if present + if(action.title !== undefined) + { + actionElem.attr('title', action.title); + } + // Adding icon class if present + if(action.icon_class !== undefined) + { + actionIconElem.addClass(action.icon_class); + } + + if(bHasSeveralSecondaryActions) + { + actionElem.append(action.title); + actionsSSMenuContainerElem.append( $('').append(actionElem) ); + } + else + { + actionsElem.append(actionElem); + } + } + + + //////////////////////////////////////////////// + + /* var actionsElem = $('').addClass('list-group-item-actions'); liElem.append(actionsElem); @@ -277,7 +353,7 @@ } actionsSSMenuContainerElem.append( $('').append(actionElem.clone()) ); actionsElem.append(actionElem.addClass('hidden-xs')); // We don't want to display it on small screens - } + }*/ } // Building subnodes if necessary diff --git a/datamodels/2.x/itop-portal-base/portal/src/views/layout.html.twig b/datamodels/2.x/itop-portal-base/portal/src/views/layout.html.twig index f8739df39..b5da9b5dc 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/views/layout.html.twig +++ b/datamodels/2.x/itop-portal-base/portal/src/views/layout.html.twig @@ -309,7 +309,6 @@ }); // Hide tooltips when a modal is opening, otherwise it might be overlapping it $('body').on('show.bs.modal', function () { - console.log('event captured'); $(this).find('.tooltip.in').tooltip('hide'); }); {% endblock %} diff --git a/datamodels/2.x/itop-portal-base/portal/web/css/portal.css b/datamodels/2.x/itop-portal-base/portal/web/css/portal.css index 5adc21bd6..2202bb4e1 100644 --- a/datamodels/2.x/itop-portal-base/portal/web/css/portal.css +++ b/datamodels/2.x/itop-portal-base/portal/web/css/portal.css @@ -458,7 +458,10 @@ label{ line-height: 1em; } .list-group-item .keep-spinning{ + animation: spin 1s linear infinite; -webkit-animation: spin 1s linear infinite; + -moz-animation: spin 1s linear infinite; + -ms-animation: spin 1s linear infinite; } /* Secondary actions */ @@ -482,6 +485,10 @@ table .group-actions .item-action-wrapper -moz-box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.15); box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.15); } +.list-group-item-actions .item-action-wrapper .glyphicon, +table .group-actions .item-action-wrapper .glyphicon{ + margin-right: 0.6em; +} .list-group-item-actions .item-action-wrapper.collapse.in, table .group-actions .item-action-wrapper.collapse.in{ display: block; @@ -633,9 +640,15 @@ table .group-actions .item-action-wrapper .panel-body > p:last-child{ } #drag_overlay.drag_in{ animation: show-drop-zone 0.3s ease-out forwards; + -webkit-animation: show-drop-zone 0.3s ease-out forwards; + -moz-animation: show-drop-zone 0.3s ease-out forwards; + -ms-animation: show-drop-zone 0.3s ease-out forwards; } #drag_overlay.drag_out{ animation: hide-drop-zone 0.3s ease-out forwards; + -webkit-animation: hide-drop-zone 0.3s ease-out forwards; + -moz-animation: hide-drop-zone 0.3s ease-out forwards; + -ms-animation: hide-drop-zone 0.3s ease-out forwards; } #drag_overlay .overlay_content{ margin-top: 5em; diff --git a/datamodels/2.x/itop-tickets/datamodel.itop-tickets.xml b/datamodels/2.x/itop-tickets/datamodel.itop-tickets.xml index bf998ffef..028644d8a 100755 --- a/datamodels/2.x/itop-tickets/datamodel.itop-tickets.xml +++ b/datamodels/2.x/itop-tickets/datamodel.itop-tickets.xml @@ -1128,6 +1128,7 @@