a9791ea419
This makes the OIDC lookup lazy, ensuring that the rest of the registry and app continues working even if one OIDC provider goes down.
295 lines
No EOL
8.9 KiB
JavaScript
295 lines
No EOL
8.9 KiB
JavaScript
|
|
/**
|
|
* The application header bar.
|
|
*/
|
|
angular.module('quay').directive('headerBar', function () {
|
|
var number = 0;
|
|
var directiveDefinitionObject = {
|
|
priority: 0,
|
|
templateUrl: '/static/directives/header-bar.html',
|
|
replace: false,
|
|
transclude: false,
|
|
restrict: 'C',
|
|
scope: {
|
|
},
|
|
controller: function($rootScope, $scope, $element, $location, $timeout, hotkeys, UserService,
|
|
PlanService, ApiService, NotificationService, Config, Features,
|
|
DocumentationService, ExternalLoginService) {
|
|
|
|
ExternalLoginService.getSingleSigninUrl(function(url) {
|
|
$scope.externalSigninUrl = url;
|
|
});
|
|
|
|
var hotkeysAdded = false;
|
|
var userUpdated = function(cUser) {
|
|
$scope.searchingAllowed = Features.ANONYMOUS_ACCESS || !cUser.anonymous;
|
|
|
|
if (hotkeysAdded) { return; }
|
|
hotkeysAdded = true;
|
|
|
|
// Register hotkeys.
|
|
if ($scope.searchingAllowed) {
|
|
hotkeys.add({
|
|
combo: '/',
|
|
description: 'Show search',
|
|
callback: function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
$scope.toggleSearch();
|
|
}
|
|
});
|
|
}
|
|
|
|
if (!cUser.anonymous) {
|
|
hotkeys.add({
|
|
combo: 'alt+c',
|
|
description: 'Create new repository',
|
|
callback: function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
$location.url('/new');
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
$scope.Config = Config;
|
|
$scope.Features = Features;
|
|
$scope.notificationService = NotificationService;
|
|
$scope.searchingAllowed = false;
|
|
$scope.searchVisible = false;
|
|
$scope.currentSearchQuery = null;
|
|
$scope.searchResultState = null;
|
|
$scope.showBuildDialogCounter = 0;
|
|
|
|
// Monitor any user changes and place the current user into the scope.
|
|
UserService.updateUserIn($scope, userUpdated);
|
|
|
|
$scope.currentPageContext = {};
|
|
|
|
$rootScope.$watch('currentPage.scope.viewuser', function(u) {
|
|
$scope.currentPageContext['viewuser'] = u;
|
|
});
|
|
|
|
$rootScope.$watch('currentPage.scope.organization', function(o) {
|
|
$scope.currentPageContext['organization'] = o;
|
|
});
|
|
|
|
$rootScope.$watch('currentPage.scope.repository', function(r) {
|
|
$scope.currentPageContext['repository'] = r;
|
|
});
|
|
|
|
var documentSearchMaxResults = 10;
|
|
var documentSearchScoreThreshold = 0.9;
|
|
|
|
var conductDocumentationSearch = function(query) {
|
|
if (!query) { return; }
|
|
|
|
var mapper = function(result, score) {
|
|
return {
|
|
'kind': 'doc',
|
|
'name': result.title.replace(/'\;/g, "'"),
|
|
'score': score,
|
|
'href': Config.DOCUMENTATION_LOCATION + result.url
|
|
}
|
|
};
|
|
|
|
DocumentationService.findDocumentation($scope, query.split(' '), function(results) {
|
|
if (!$scope.searchVisible) { return; }
|
|
|
|
var currentResults = $scope.searchResultState['results'] || [];
|
|
results.forEach(function(result) {
|
|
if (currentResults.length < documentSearchMaxResults) {
|
|
currentResults.push(result);
|
|
}
|
|
});
|
|
|
|
$scope.searchResultState = {
|
|
'state': currentResults.length ? 'results' : 'no-results',
|
|
'results': currentResults,
|
|
'current': currentResults.length ? 0 : -1
|
|
};
|
|
}, mapper, documentSearchScoreThreshold);
|
|
}
|
|
|
|
var conductSearch = function(query) {
|
|
if (!query) { $scope.searchResultState = null; return; }
|
|
|
|
$scope.searchResultState = {
|
|
'state': 'loading'
|
|
};
|
|
|
|
var params = {
|
|
'query': query
|
|
};
|
|
|
|
ApiService.conductSearch(null, params).then(function(resp) {
|
|
if (!$scope.searchVisible || query != $scope.currentSearchQuery) { return; }
|
|
|
|
$scope.searchResultState = {
|
|
'state': resp.results.length ? 'results' : 'no-results',
|
|
'results': resp.results,
|
|
'current': resp.results.length ? 0 : -1
|
|
};
|
|
|
|
if (resp.results.length < documentSearchMaxResults) {
|
|
conductDocumentationSearch(query);
|
|
}
|
|
}, function(resp) {
|
|
$scope.searchResultState = null;
|
|
}, /* background */ true);
|
|
};
|
|
|
|
$scope.$watch('currentSearchQuery', conductSearch);
|
|
|
|
$scope.signout = function() {
|
|
ApiService.logout().then(function() {
|
|
UserService.load();
|
|
$location.path('/');
|
|
});
|
|
};
|
|
|
|
$scope.getEnterpriseLogo = function() {
|
|
return Config.getEnterpriseLogo();
|
|
};
|
|
|
|
$scope.toggleSearch = function() {
|
|
$scope.searchVisible = !$scope.searchVisible;
|
|
if ($scope.searchVisible) {
|
|
$('#search-box-input').focus();
|
|
if ($scope.currentSearchQuery) {
|
|
conductSearch($scope.currentSearchQuery);
|
|
}
|
|
} else {
|
|
$('#search-box-input').blur()
|
|
$scope.searchResultState = null;
|
|
}
|
|
};
|
|
|
|
$scope.getSearchBoxClasses = function(searchVisible, searchResultState) {
|
|
var classes = searchVisible ? 'search-visible ' : '';
|
|
if (searchResultState) {
|
|
classes += 'results-visible';
|
|
}
|
|
return classes;
|
|
};
|
|
|
|
$scope.handleSearchKeyDown = function(e) {
|
|
if (e.keyCode == 27) {
|
|
$scope.toggleSearch();
|
|
return;
|
|
}
|
|
|
|
var state = $scope.searchResultState;
|
|
if (!state || !state['results']) { return; }
|
|
|
|
if (e.keyCode == 40) {
|
|
state['current']++;
|
|
e.preventDefault();
|
|
} else if (e.keyCode == 38) {
|
|
state['current']--;
|
|
e.preventDefault();
|
|
} else if (e.keyCode == 13) {
|
|
var current = state['current'];
|
|
if (current >= 0 && current < state['results'].length) {
|
|
$scope.showResult(state['results'][current]);
|
|
}
|
|
e.preventDefault();
|
|
}
|
|
|
|
if (state['current'] < -1) {
|
|
state['current'] = state['results'].length - 1;
|
|
} else if (state['current'] >= state['results'].length) {
|
|
state['current'] = 0;
|
|
}
|
|
};
|
|
|
|
$scope.showResult = function(result) {
|
|
$scope.toggleSearch();
|
|
$timeout(function() {
|
|
if (result['kind'] == 'doc') {
|
|
window.location = result['href'];
|
|
return;
|
|
}
|
|
|
|
$scope.currentSearchQuery = '';
|
|
$location.url(result['href'])
|
|
}, 500);
|
|
};
|
|
|
|
$scope.setCurrentResult = function(result) {
|
|
if (!$scope.searchResultState) { return; }
|
|
$scope.searchResultState['current'] = result;
|
|
};
|
|
|
|
$scope.getNamespace = function(context) {
|
|
if (!context) { return null; }
|
|
|
|
if (context.repository && context.repository.namespace) {
|
|
return context.repository.namespace;
|
|
}
|
|
|
|
if (context.organization && context.organization.name) {
|
|
return context.organization.name;
|
|
}
|
|
|
|
if (context.viewuser && context.viewuser.username) {
|
|
return context.viewuser.username;
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
$scope.canAdmin = function(namespace) {
|
|
if (!namespace) { return false; }
|
|
return UserService.isNamespaceAdmin(namespace);
|
|
};
|
|
|
|
$scope.isOrganization = function(namespace) {
|
|
if (!namespace) { return false; }
|
|
return UserService.isOrganization(namespace);
|
|
};
|
|
|
|
$scope.startBuild = function(context) {
|
|
$scope.showBuildDialogCounter++;
|
|
};
|
|
|
|
$scope.handleBuildStarted = function(build, context) {
|
|
$location.url('/repository/' + context.repository.namespace + '/' + context.repository.name + '/build/' + build.id);
|
|
};
|
|
|
|
$scope.handleRobotCreated = function(created, context) {
|
|
var namespace = $scope.getNamespace(context);
|
|
if (UserService.isOrganization(namespace)) {
|
|
$location.url('/organization/' + namespace + '?tab=robots&showRobot=' + created.name);
|
|
} else {
|
|
$location.url('/user/' + namespace + '?tab=robots&showRobot=' + created.name);
|
|
}
|
|
};
|
|
|
|
$scope.handleTeamCreated = function(created, context) {
|
|
var namespace = $scope.getNamespace(context);
|
|
$location.url('/organization/' + namespace + '/teams/' + created.name);
|
|
};
|
|
|
|
$scope.askCreateRobot = function(context) {
|
|
var namespace = $scope.getNamespace(context);
|
|
if (!namespace || !UserService.isNamespaceAdmin(namespace)) { return; }
|
|
|
|
$scope.createRobotInfo = {
|
|
'namespace': namespace
|
|
};
|
|
};
|
|
|
|
$scope.askCreateTeam = function(context) {
|
|
var namespace = $scope.getNamespace(context);
|
|
if (!namespace || !UserService.isNamespaceAdmin(namespace)) { return; }
|
|
|
|
$scope.createTeamInfo = {
|
|
'namespace': namespace
|
|
};
|
|
};
|
|
}
|
|
};
|
|
return directiveDefinitionObject;
|
|
}); |