From 5ebcb4122447ca05aa022fa8a0ccab0e1598d3b7 Mon Sep 17 00:00:00 2001 From: Guillaume Lajarige Date: Tue, 14 Mar 2017 13:59:05 +0000 Subject: [PATCH] Portal: Added breadcrumbs to grid mode of the BrowseBrick SVN:trunk[4584] --- .../src/views/bricks/browse/layout.html.twig | 2 +- .../views/bricks/browse/mode_grid.html.twig | 144 +++++++++++------- .../portal/web/css/portal.css | 28 +++- .../portal/web/css/portal.scss | 29 +++- 4 files changed, 149 insertions(+), 54 deletions(-) diff --git a/datamodels/2.x/itop-portal-base/portal/src/views/bricks/browse/layout.html.twig b/datamodels/2.x/itop-portal-base/portal/src/views/bricks/browse/layout.html.twig index 9316b23b7..27ccf2918 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/views/bricks/browse/layout.html.twig +++ b/datamodels/2.x/itop-portal-base/portal/src/views/bricks/browse/layout.html.twig @@ -31,4 +31,4 @@ {% endif %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/datamodels/2.x/itop-portal-base/portal/src/views/bricks/browse/mode_grid.html.twig b/datamodels/2.x/itop-portal-base/portal/src/views/bricks/browse/mode_grid.html.twig index 9c291ff2e..f9b4cfb05 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/views/bricks/browse/mode_grid.html.twig +++ b/datamodels/2.x/itop-portal-base/portal/src/views/bricks/browse/mode_grid.html.twig @@ -5,6 +5,9 @@ {% block bBrowseMainContent %}
{% block bBrowseGridContent %} +
{% endblock %} @@ -47,66 +50,49 @@ $('#brick_grid_overlay').hide(); $("#brick_content_grid").show(); } + // Show the requested level + var showLevel = function(sLevelAlias, sItemId) + { + // Retrieving level to show + var sLevelId = sLevelAlias + ((sItemId !== undefined) ? '::'+sItemId : '' ); + var oLevelElem = $('#brick_content_grid .grid-group[data-level-id="' + sLevelId + '"]'); + var bLevelLoaded = (oLevelElem.length > 0); + + // Hiding current level + $('#brick_content_grid .grid-group:visible').hide( + sGridEffectName, + oGridEffectOptions, + iGridEffectDuration, + function(){ + // Showing level + if(!bLevelLoaded) + { + showGridLoader(); + loadChildNodes(sLevelAlias, sItemId); + } + else + { + oLevelElem.show(sGridEffectName, oGridEffectOptions, iGridEffectDuration, function(){ buildBreadcrumb(); }); + } + } + ); + }; // Registers the toggle listeners on the tree nodes. Used after every AJAX calls. var registerToggleListeners = function() { $('#brick_content_grid .grid-drilldown').off('click').on('click', function (oEvent) { oEvent.preventDefault(); - var me = this; - // Retrieving sublevel - var sublevelId = $(this).attr('data-level-alias') + '::' + $(this).attr('data-item-id'); - var sublevelElem = $('#brick_content_grid .grid-group[data-level-id="'+sublevelId+'"]'); - - // Hidding current level - if(sublevelElem.length === 0) - { - showGridLoader(); - } - $(this).closest('.grid-group').hide( - sGridEffectName, - oGridEffectOptions, - iGridEffectDuration, - function(){ - // Showing sublevel - if(sublevelElem.length === 0) - { - loadChildNodes($(me).attr('data-level-alias'), $(me).attr('data-item-id')); - } - else - { - sublevelElem.show(sGridEffectName, oGridEffectOptions, iGridEffectDuration); - } - } - ); + showLevel($(this).attr('data-level-alias'), $(this).attr('data-item-id')); }); $('#brick_content_grid .grid-rollup').off('click').on('click', function (oEvent) { oEvent.preventDefault(); - // Retrieving upper level var upperlevelId = $(this).attr('data-level-id'); - var upperlevelElem = $('#brick_content_grid .grid-group[data-level-id="'+upperlevelId+'"]'); + var upperlevelIdParts = upperlevelId.split('::'); - // Hidding current level - $(this).closest('.grid-group').hide( - sGridEffectName, - oGridEffectOptions, - iGridEffectDuration, - function(){ - // Showing upper level - if(upperlevelElem.length === 0) - { - var upperlevelIdParts = upperlevelId.split('::'); - - loadChildNodes(upperlevelIdParts[0], upperlevelIdParts[1]); - } - else - { - upperlevelElem.show(sGridEffectName, oGridEffectOptions, iGridEffectDuration); - } - } - ); + showLevel(upperlevelIdParts[0], upperlevelIdParts[1]); }); }; // Registers the filter listeners on the tree. @@ -131,7 +117,7 @@ buildGrid(sublevelData, sLevelAlias+"::"+sNodeId, false); } // Showing sublevel - $('#brick_content_grid .grid-group[data-level-id="'+sLevelAlias+"::"+sNodeId+'"]').show(sGridEffectName, oGridEffectOptions, iGridEffectDuration); + $('#brick_content_grid .grid-group[data-level-id="'+sLevelAlias+"::"+sNodeId+'"]').show(sGridEffectName, oGridEffectOptions, iGridEffectDuration, function(){ buildBreadcrumb(); }); registerToggleListeners(); }) @@ -142,7 +128,7 @@ hideGridLoader(); }); }; - // Build tree nodes from data under the nodeId + // Build grid nodes from data under the nodeId var buildGrid = function(data, nodeId, isRootLevel) { if(nodeId === undefined) @@ -205,13 +191,13 @@ if( (item.name !== undefined) && (item.name !== '') ) { iItemFlags += 1; - textElem.append( $('
').addClass('grid-item-name').text(item.name) ); + textElem.append( $('
').addClass('grid-item-name').html(item.name) ); } // - Adding description if( (item.description !== undefined) && (item.description !== '') ) { iItemFlags += 2; - textElem.append( $('
').addClass('grid-item-description').text(item.description) ); + textElem.append( $('
').addClass('grid-item-description').html(item.description) ); } aElem.append( textElem ); // - Adding CSS class to adjust the layout regarding which properties are available @@ -348,6 +334,62 @@ registerToggleListeners(); } }; + // Build breadcrumb + var buildBreadcrumb = function(oCurrentElem) + { + var aCurrentLevelParts = []; + + // If no current item, it's because we begin to build the breadcrumb, starting from the bottom + if(oCurrentElem === undefined) + { + // Retrieving current level id + var sCurrentLevelId = $('#brick_content_grid > .grid-group:visible').attr('data-level-id'); + aCurrentLevelParts = sCurrentLevelId.split('::'); + + // Emptying breadcrumb + $('#grid-breadcrumb > li:not(:first-of-type)').remove(); + + // Finding current item + oCurrentElem = $('#brick_content_grid .grid-item[data-level-alias="'+aCurrentLevelParts[0]+'"][data-item-id="'+aCurrentLevelParts[1]+'"]'); + if(oCurrentElem.length === 0) + { + return false; + } + } + else + { + aCurrentLevelParts = [oCurrentElem.attr('data-level-alias'), oCurrentElem.attr('data-item-id')]; + } + + // Adding level as crumb + var oCrumb = $('
  • ').html( oCurrentElem.find('.grid-item-name').html() ); + oCrumb.addClass('grid-crumb'); + oCrumb.attr('data-level-id', aCurrentLevelParts.join('::')); + oCrumb.insertAfter('#grid-breadcrumb > li:first-of-type'); + // Adding listener + $('#grid-breadcrumb > li:not(:last-of-type)').off('click').on('click', function(oEvent){ + oEvent.preventDefault(); + + var levelId = $(this).attr('data-level-id'); + var levelIdParts = levelId.split('::'); + + showLevel(levelIdParts[0], levelIdParts[1]); + }); + + // Finding parent level + var oParentLevelElem = oCurrentElem.closest('.grid-group'); + if(oParentLevelElem.length > 0) + { + var sParentLevelId = oParentLevelElem.attr('data-level-id'); + var aParentLevelParts = sParentLevelId.split('::'); + var oParentElem = $('#brick_content_grid .grid-item[data-level-alias="'+aParentLevelParts[0]+'"][data-item-id="'+aParentLevelParts[1]+'"]'); + + if(oParentElem.length === 1) + { + buildBreadcrumb(oParentElem); + } + } + }; $(document).ready(function(){ // Auto collapse item actions popup 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 e2a382a01..b627b42e0 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 @@ -622,11 +622,37 @@ table .group-actions { position: relative; padding: 10px 10px 1px 10px; } +/* Breadcrumb */ +#grid-breadcrumb { + padding-left: 0px; + font-size: 12px; +} +#grid-breadcrumb > li { + display: inline; + cursor: pointer; + color: #ea7d1e; +} +#grid-breadcrumb > li:hover { + color: #d56e14; +} +#grid-breadcrumb > li:last-of-type { + color: inherit; + cursor: inherit; +} +#grid-breadcrumb > li:after { + content: '/'; + margin-left: 0.4em; + margin-right: 0.2em; + color: initial; +} +#grid-breadcrumb > li:last-of-type:after { + content: none; +} .grid-group { display: none; } /* Only the first level is showed by default */ -.grid-group:first-child { +.grid-group:first-of-type { display: block; } .grid-group-back, .grid-group-item { diff --git a/datamodels/2.x/itop-portal-base/portal/web/css/portal.scss b/datamodels/2.x/itop-portal-base/portal/web/css/portal.scss index 3a05d550f..be95ed0cc 100644 --- a/datamodels/2.x/itop-portal-base/portal/web/css/portal.scss +++ b/datamodels/2.x/itop-portal-base/portal/web/css/portal.scss @@ -669,11 +669,38 @@ table .group-actions .item-action-wrapper .panel-body > p:last-child{ position: relative; padding: 10px 10px 1px 10px; } +/* Breadcrumb */ +#grid-breadcrumb{ + padding-left: 0px; + font-size: 12px; +} +#grid-breadcrumb > li{ + display: inline; + cursor: pointer; + color: $brand-primary; +} +#grid-breadcrumb > li:hover{ + color: $brand-primary-dark; +} +#grid-breadcrumb > li:last-of-type{ + color: inherit; + cursor: inherit; +} +#grid-breadcrumb > li:after{ + content: '/'; + margin-left: 0.4em; + margin-right: 0.2em; + color: initial; +} +#grid-breadcrumb > li:last-of-type:after{ + content: none; +} + .grid-group{ display: none; } /* Only the first level is showed by default */ -.grid-group:first-child{ +.grid-group:first-of-type{ display: block; }