Systematically truncate breadcrumbs based on their length to keep them inside the breadcrumb bar. This does not work on inventory manage breadcrumbs as those are controlled via a different mechanism.

This commit is contained in:
Michael Abashian 2017-01-03 17:11:10 -05:00
parent 6fcda9c562
commit 006acadc25
13 changed files with 125 additions and 8 deletions

View File

@ -66,7 +66,6 @@
display: inline-block;
color: @default-interface-txt;
text-transform: uppercase;
max-width: 200px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;

View File

@ -1,6 +1,6 @@
export default
['templateUrl', '$state', 'FeaturesService', 'ProcessErrors','$rootScope', 'Store', 'Empty',
function(templateUrl, $state, FeaturesService, ProcessErrors, $rootScope, Store, Empty) {
['templateUrl', '$state', 'FeaturesService', 'ProcessErrors','$rootScope', 'Store', 'Empty', '$window', 'BreadCrumbService',
function(templateUrl, $state, FeaturesService, ProcessErrors, $rootScope, Store, Empty, $window, BreadCrumbService) {
return {
restrict: 'E',
templateUrl: templateUrl('bread-crumb/bread-crumb'),
@ -8,9 +8,25 @@ export default
var streamConfig = {}, originalRoute;
scope.showActivityStreamButton = false;
scope.showRefreshButton = false;
scope.loadingLicense = true;
function init() {
scope.showActivityStreamButton = false;
scope.showRefreshButton = false;
scope.loadingLicense = true;
function onResize(){
BreadCrumbService.truncateCrumbs();
}
function cleanUp() {
angular.element($window).off('resize', onResize);
}
angular.element($window).on('resize', onResize);
scope.$on('$destroy', cleanUp);
}
init();
scope.refresh = function() {
$state.go($state.current, {}, {reload: true});

View File

@ -30,4 +30,5 @@
</i>
</div>
</div>
<div id="bread_crumb_width_checker" style="visibility:hidden"></div>
</div>

View File

@ -0,0 +1,79 @@
export default
[function(){
return {
truncateCrumbs: function(){
let breadCrumbBarWidth = $('#bread_crumb').outerWidth();
let menuLinkWidth = $('.BreadCrumb-menuLinkHolder').outerWidth();
let availableWidth = breadCrumbBarWidth - menuLinkWidth;
let $breadcrumbClone = $('.BreadCrumb-list').clone().appendTo('#bread_crumb_width_checker');
let $breadcrumbCloneItems = $breadcrumbClone.find('.BreadCrumb-item');
// 40px for the padding on the breadcrumb bar and a few extra pixels for rounding
let expandedBreadcrumbWidth = 45;
let crumbs = [];
$breadcrumbCloneItems.css('max-width', 'none');
$breadcrumbCloneItems.each(function(index, item){
let crumbWidth = $(item).outerWidth();
expandedBreadcrumbWidth += crumbWidth;
crumbs.push({
index: index,
origWidth: crumbWidth
});
});
// Remove the clone from the dom
$breadcrumbClone.remove();
if(expandedBreadcrumbWidth > availableWidth) {
let widthToTrim = expandedBreadcrumbWidth - availableWidth;
// Sort the crumbs from biggest to smallest
let sortedCrumbs = _.sortByOrder(crumbs, ["origWidth"], ["desc"]);
let maxWidth;
for(let i=0; i<sortedCrumbs.length; i++) {
if(sortedCrumbs[i+1]) {
// This isn't the smallest crumb
if(sortedCrumbs[i-1]) {
// This isn't the biggest crumb
let potentialCrumbsToTrim = i+1;
if(potentialCrumbsToTrim*(sortedCrumbs[i].origWidth - sortedCrumbs[i+1].origWidth) > widthToTrim) {
// If we trim down the biggest (i+1) crumbs equally then we can make it fit
maxWidth = maxWidth - (widthToTrim/potentialCrumbsToTrim);
break;
}
else {
// Trim this biggest crumb down to the next biggest
widthToTrim = widthToTrim - (sortedCrumbs[i].origWidth - sortedCrumbs[i+1].origWidth);
maxWidth = sortedCrumbs[i].origWidth;
}
}
else {
// This is the biggest crumb
if(sortedCrumbs[i].origWidth - widthToTrim > sortedCrumbs[i+1].origWidth) {
maxWidth = sortedCrumbs[i].origWidth - widthToTrim;
break;
}
else {
// Trim this biggest crumb down to the next biggest
widthToTrim = widthToTrim - (sortedCrumbs[i].origWidth - sortedCrumbs[i+1].origWidth);
maxWidth = sortedCrumbs[i+1].origWidth;
}
}
}
else {
// This is the smallest crumb
if(sortedCrumbs[i-1]) {
// We've gotten all the way down to the smallest crumb without being able to reasonably trim
// the previous crumbs. Go ahead and trim all of them equally.
maxWidth = availableWidth/(i+1);
}
else {
// There's only one breadcrumb so trim this one down
maxWidth = sortedCrumbs[i].origWidth - widthToTrim;
}
}
}
$('.BreadCrumb-item').css('max-width', maxWidth);
}
else {
$('.BreadCrumb-item').css('max-width', 'none');
}
}
};
}];

View File

@ -1,5 +1,7 @@
import breadCrumb from './bread-crumb.directive';
import breadCrumbService from './bread-crumb.service';
export default
angular.module('breadCrumb', [])
.service('BreadCrumbService', breadCrumbService)
.directive('breadCrumb', breadCrumb);

View File

@ -29,6 +29,7 @@ export default ['$stateParams', '$scope', 'UserList', 'Rest', '$state',
Rest.get()
.success(function(data) {
$scope.organization_name = data.name;
$scope.name = data.name;
$scope.org_id = data.id;
$scope.orgRelatedUrls = data.related;

View File

@ -31,6 +31,7 @@ export default ['$scope', '$rootScope', '$location', '$log',
.success(function(data) {
$scope.organization_name = data.name;
$scope.name = data.name;
$scope.org_id = data.id;
$scope.orgRelatedUrls = data.related;

View File

@ -32,6 +32,7 @@ export default ['$scope', '$rootScope', '$location', '$log',
Rest.get()
.success(function(data) {
$scope.organization_name = data.name;
$scope.name = data.name;
$scope.org_id = data.id;
$scope.orgRelatedUrls = data.related;

View File

@ -104,6 +104,7 @@ export default ['$scope', '$rootScope', '$location', '$log',
Rest.get()
.success(function(data) {
$scope.organization_name = data.name;
$scope.name = data.name;
$scope.org_id = data.id;
$scope.orgRelatedUrls = data.related;

View File

@ -37,6 +37,7 @@ export default ['$scope', '$rootScope', '$location', '$log', '$stateParams', 'Or
.success(function(data) {
$scope.organization_name = data.name;
$scope.name = data.name;
$scope.org_id = data.id;
$scope.orgRelatedUrls = data.related;

View File

@ -29,6 +29,7 @@ export default ['$stateParams', '$scope', 'OrgUserList', 'AddUserList','Rest', '
Rest.get()
.success(function(data) {
$scope.organization_name = data.name;
$scope.name = data.name;
$scope.org_id = data.id;
$scope.orgRelatedUrls = data.related;

View File

@ -1,8 +1,8 @@
<ol class="BreadCrumb-list">
<li class="BreadCrumb-item" ng-repeat="step in steps | limitTo:(steps.length-1)">
<li class="BreadCrumb-item" ng-repeat="step in steps | limitTo:(steps.length-1)" aw-truncate-breadcrumb breadcrumb-step="step">
<a href="{{step.ncyBreadcrumbLink}}">{{step.ncyBreadcrumbLabel|translate}}</a>
</li>
<li class="BreadCrumb-item" ng-repeat="step in steps | limitTo:-1" class="active">
<li class="BreadCrumb-item" ng-repeat="step in steps | limitTo:-1" class="active" aw-truncate-breadcrumb breadcrumb-step="step">
<span>{{step.ncyBreadcrumbLabel|translate}}</span>
</li>
</ol>

View File

@ -1168,4 +1168,18 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'JobsHelper'])
});
}
};
}])
.directive('awTruncateBreadcrumb', ['BreadCrumbService', function(BreadCrumbService) {
return {
restrict: 'A',
scope: {
breadcrumbStep: '='
},
link: function(scope) {
scope.$watch('breadcrumbStep.ncyBreadcrumbLabel', function(){
BreadCrumbService.truncateCrumbs();
});
}
};
}]);