- Add a dropdown-select directive and use it in the git trigger setup dialog both times
- Add a dropdown-select for the docker file folder - Add an API method for listing the build source sub directories
This commit is contained in:
parent
4b0f4c0a7b
commit
d1fdc31549
8 changed files with 331 additions and 59 deletions
241
static/js/app.js
241
static/js/app.js
|
@ -102,7 +102,7 @@ function getMarkedDown(string) {
|
|||
return Markdown.getSanitizingConverter().makeHtml(string || '');
|
||||
}
|
||||
|
||||
quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'angular-tour', 'restangular', 'angularMoment', 'angulartics', /*'angulartics.google.analytics',*/ 'angulartics.mixpanel', '$strap.directives', 'ngCookies', 'ngSanitize', 'angular-md5', 'pasvaz.bindonce', 'ansiToHtml'], function($provide, cfpLoadingBarProvider) {
|
||||
quayApp = angular.module('quay', ['ngRoute', 'chieffancypants.loadingBar', 'angular-tour', 'restangular', 'angularMoment', 'angulartics', /*'angulartics.google.analytics',*/ 'angulartics.mixpanel', '$strap.directives', 'ngCookies', 'ngSanitize', 'angular-md5', 'pasvaz.bindonce', 'ansiToHtml', 'ngAnimate'], function($provide, cfpLoadingBarProvider) {
|
||||
cfpLoadingBarProvider.includeSpinner = false;
|
||||
|
||||
$provide.factory('UtilService', ['$sanitize', function($sanitize) {
|
||||
|
@ -2544,6 +2544,139 @@ quayApp.directive('triggerDescription', function () {
|
|||
});
|
||||
|
||||
|
||||
quayApp.directive('dropdownSelect', function ($compile) {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 0,
|
||||
templateUrl: '/static/directives/dropdown-select.html',
|
||||
replace: true,
|
||||
transclude: true,
|
||||
restrict: 'C',
|
||||
scope: {
|
||||
'selectedItem': '=selectedItem',
|
||||
'enteredText': '=enteredText',
|
||||
'placeholder': '=placeholder',
|
||||
'lookaheadItems': '=lookaheadItems',
|
||||
'handleItemSelected': '&handleItemSelected',
|
||||
'handleInput': '&handleInput'
|
||||
},
|
||||
controller: function($scope, $element, $rootScope) {
|
||||
if (!$rootScope.__dropdownSelectCounter) {
|
||||
$rootScope.__dropdownSelectCounter = 1;
|
||||
}
|
||||
|
||||
$scope.placeholder = $scope.placeholder || '';
|
||||
$scope.internalItem = null;
|
||||
|
||||
// Setup lookahead.
|
||||
var input = $($element).find('.lookahead-input');
|
||||
|
||||
$scope.$watch('selectedItem', function(item) {
|
||||
if ($scope.selectedItem == $scope.internalItem) {
|
||||
// The item has already been set due to an internal action.
|
||||
return;
|
||||
}
|
||||
|
||||
if ($scope.selectedItem != null) {
|
||||
$(input).val(item.toString());
|
||||
} else {
|
||||
$(input).val('');
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$watch('lookaheadItems', function(items) {
|
||||
$(input).off();
|
||||
if (!items) {
|
||||
return;
|
||||
}
|
||||
|
||||
$(input).typeahead({
|
||||
name: 'dropdown-items-' + $rootScope.__dropdownSelectCounter,
|
||||
local: items,
|
||||
template: function (datum) {
|
||||
template = datum['template'] ? datum['template'](datum) : datum['value'];
|
||||
return template;
|
||||
}
|
||||
});
|
||||
|
||||
$(input).on('input', function(e) {
|
||||
$scope.$apply(function() {
|
||||
$scope.internalItem = null;
|
||||
$scope.selectedItem = null;
|
||||
if ($scope.handleInput) {
|
||||
$scope.handleInput({'input': $(input).val()});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(input).on('typeahead:selected', function(e, datum) {
|
||||
$scope.$apply(function() {
|
||||
$scope.internalItem = datum['item'] || datum['value'];
|
||||
$scope.selectedItem = datum['item'] || datum['value'];
|
||||
if ($scope.handleItemSelected) {
|
||||
$scope.handleItemSelected({'datum': datum});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$rootScope.__dropdownSelectCounter++;
|
||||
});
|
||||
},
|
||||
link: function(scope, element, attrs) {
|
||||
var transcludedBlock = element.find('div.transcluded');
|
||||
var transcludedElements = transcludedBlock.children();
|
||||
|
||||
var iconContainer = element.find('div.dropdown-select-icon-transclude');
|
||||
var menuContainer = element.find('div.dropdown-select-menu-transclude');
|
||||
|
||||
angular.forEach(transcludedElements, function(elem) {
|
||||
if (angular.element(elem).hasClass('dropdown-select-icon')) {
|
||||
iconContainer.append(elem);
|
||||
} else if (angular.element(elem).hasClass('dropdown-select-menu')) {
|
||||
menuContainer.replaceWith(elem);
|
||||
}
|
||||
});
|
||||
|
||||
transcludedBlock.remove();
|
||||
}
|
||||
};
|
||||
return directiveDefinitionObject;
|
||||
});
|
||||
|
||||
|
||||
quayApp.directive('dropdownSelectIcon', function () {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 1,
|
||||
require: '^dropdownSelect',
|
||||
templateUrl: '/static/directives/dropdown-select-icon.html',
|
||||
replace: false,
|
||||
transclude: false,
|
||||
restrict: 'C',
|
||||
scope: {
|
||||
},
|
||||
controller: function($scope, $element) {
|
||||
}
|
||||
};
|
||||
return directiveDefinitionObject;
|
||||
});
|
||||
|
||||
|
||||
quayApp.directive('dropdownSelectMenu', function () {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 1,
|
||||
require: '^dropdownSelect',
|
||||
templateUrl: '/static/directives/dropdown-select-menu.html',
|
||||
replace: true,
|
||||
transclude: true,
|
||||
restrict: 'C',
|
||||
scope: {
|
||||
},
|
||||
controller: function($scope, $element) {
|
||||
}
|
||||
};
|
||||
return directiveDefinitionObject;
|
||||
});
|
||||
|
||||
|
||||
quayApp.directive('triggerSetupGithub', function () {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 0,
|
||||
|
@ -2558,48 +2691,86 @@ quayApp.directive('triggerSetupGithub', function () {
|
|||
controller: function($scope, $element, ApiService) {
|
||||
$scope.setupReady = false;
|
||||
$scope.loading = true;
|
||||
|
||||
var input = $($element).find('.lookahead-input');
|
||||
|
||||
$scope.clearSelectedRepo = function() {
|
||||
$scope.currentRepo = null;
|
||||
$scope.trigger.$ready = false;
|
||||
|
||||
$scope.setLocation = function(location) {
|
||||
$scope.currentLocation = location;
|
||||
$scope.trigger['config']['subdir'] = location || '';
|
||||
};
|
||||
|
||||
|
||||
$scope.selectRepo = function(repo, org) {
|
||||
$(input).val(repo);
|
||||
$scope.selectRepoInternal(repo, org);
|
||||
};
|
||||
|
||||
$scope.selectRepoInternal = function(repo, org) {
|
||||
$scope.currentRepo = {
|
||||
'name': repo,
|
||||
'avatar_url': org['info']['avatar_url']
|
||||
'repo': repo,
|
||||
'avatar_url': org['info']['avatar_url'],
|
||||
'toString': function() {
|
||||
return this.repo;
|
||||
}
|
||||
};
|
||||
$scope.trigger['config'] = {
|
||||
'build_source': repo
|
||||
};
|
||||
$scope.trigger.$ready = true;
|
||||
};
|
||||
|
||||
var setupTypeahead = function() {
|
||||
$scope.selectRepoInternal = function(currentRepo) {
|
||||
if (!currentRepo) {
|
||||
$scope.trigger.$ready = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var params = {
|
||||
'repository': $scope.repository.namespace + '/' + $scope.repository.name,
|
||||
'trigger_uuid': $scope.trigger['id']
|
||||
};
|
||||
|
||||
var repo = currentRepo['repo'];
|
||||
$scope.trigger['config'] = {
|
||||
'build_source': repo,
|
||||
'subdir': ''
|
||||
};
|
||||
|
||||
// Lookup the possible Dockerfile locations.
|
||||
$scope.locations = null;
|
||||
if (repo) {
|
||||
ApiService.listBuildTriggerSubdirs($scope.trigger['config'], params).then(function(resp) {
|
||||
if (resp['status'] == 'error') {
|
||||
$scope.locationError = resp['message'] || 'Could not load Dockerfile locations';
|
||||
$scope.locations = null;
|
||||
$scope.trigger.$ready = false;
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.locationError = null;
|
||||
$scope.locations = resp['subdir'] || [];
|
||||
$scope.trigger.$ready = true;
|
||||
}, function(resp) {
|
||||
$scope.locationError = resp['message'] || 'Could not load Dockerfile locations';
|
||||
$scope.locations = null;
|
||||
$scope.trigger.$ready = false;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var setupTypeahead = function() {
|
||||
var repos = [];
|
||||
for (var i = 0; i < $scope.orgs.length; ++i) {
|
||||
var org = $scope.orgs[i];
|
||||
var orepos = org['repos'];
|
||||
for (var j = 0; j < orepos.length; ++j) {
|
||||
repos.push({'name': orepos[j], 'org': org, 'value': orepos[j]});
|
||||
var repoValue = {
|
||||
'repo': orepos[j],
|
||||
'avatar_url': org['info']['avatar_url'],
|
||||
'toString': function() {
|
||||
return this.repo;
|
||||
}
|
||||
};
|
||||
var datum = {
|
||||
'name': orepos[j],
|
||||
'org': org,
|
||||
'value': orepos[j],
|
||||
'title': orepos[j],
|
||||
'item': repoValue
|
||||
};
|
||||
repos.push(datum);
|
||||
}
|
||||
}
|
||||
|
||||
$(input).typeahead({
|
||||
name: 'repos-' + $scope.trigger.id,
|
||||
local: repos,
|
||||
template: function (datum) {
|
||||
template = datum['name'];
|
||||
return template;
|
||||
}
|
||||
});
|
||||
$scope.repoLookahead = repos;
|
||||
};
|
||||
|
||||
var loadSources = function() {
|
||||
|
@ -2617,16 +2788,8 @@ quayApp.directive('triggerSetupGithub', function () {
|
|||
|
||||
loadSources();
|
||||
|
||||
$(input).on('input', function(e) {
|
||||
$scope.$apply(function() {
|
||||
$scope.clearSelectedRepo();
|
||||
});
|
||||
});
|
||||
|
||||
$(input).on('typeahead:selected', function(e, datum) {
|
||||
$scope.$apply(function() {
|
||||
$scope.selectRepoInternal(datum.repo, datum.org);
|
||||
});
|
||||
$scope.$watch('currentRepo', function(repo) {
|
||||
$scope.selectRepoInternal(repo);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
Reference in a new issue