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