- 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
|
@ -29,7 +29,7 @@ from auth.permissions import (ReadRepositoryPermission,
|
||||||
ViewTeamPermission,
|
ViewTeamPermission,
|
||||||
UserPermission)
|
UserPermission)
|
||||||
from endpoints.common import common_login, get_route_data, truthy_param
|
from endpoints.common import common_login, get_route_data, truthy_param
|
||||||
from endpoints.trigger import BuildTrigger, TriggerActivationException
|
from endpoints.trigger import BuildTrigger, TriggerActivationException, EmptyRepositoryException
|
||||||
from util.cache import cache_control
|
from util.cache import cache_control
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
@ -1369,6 +1369,39 @@ def _prepare_webhook_url(scheme, username, password, hostname, path):
|
||||||
return urlparse.urlunparse((scheme, auth_hostname, path, '', '', ''))
|
return urlparse.urlunparse((scheme, auth_hostname, path, '', '', ''))
|
||||||
|
|
||||||
|
|
||||||
|
@api.route('/repository/<path:repository>/trigger/<trigger_uuid>/subdir',
|
||||||
|
methods=['POST'])
|
||||||
|
@api_login_required
|
||||||
|
@parse_repository_name
|
||||||
|
def list_build_trigger_subdirs(namespace, repository, trigger_uuid):
|
||||||
|
permission = AdministerRepositoryPermission(namespace, repository)
|
||||||
|
if permission.can():
|
||||||
|
try:
|
||||||
|
trigger = model.get_build_trigger(namespace, repository, trigger_uuid)
|
||||||
|
except model.InvalidBuildTriggerException:
|
||||||
|
abort(404)
|
||||||
|
return
|
||||||
|
|
||||||
|
handler = BuildTrigger.get_trigger_for_service(trigger.service.name)
|
||||||
|
user_permission = UserPermission(trigger.connected_user.username)
|
||||||
|
if user_permission.can():
|
||||||
|
new_config_dict = request.get_json()
|
||||||
|
|
||||||
|
try:
|
||||||
|
subdirs = handler.list_build_subdirs(trigger.auth_token, new_config_dict)
|
||||||
|
return jsonify({
|
||||||
|
'subdir': subdirs,
|
||||||
|
'status': 'success'
|
||||||
|
})
|
||||||
|
except EmptyRepositoryException as e:
|
||||||
|
return jsonify({
|
||||||
|
'status': 'error',
|
||||||
|
'message': e.msg
|
||||||
|
})
|
||||||
|
|
||||||
|
abort(403) # Permission denied
|
||||||
|
|
||||||
|
|
||||||
@api.route('/repository/<path:repository>/trigger/<trigger_uuid>/activate',
|
@api.route('/repository/<path:repository>/trigger/<trigger_uuid>/activate',
|
||||||
methods=['POST'])
|
methods=['POST'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
|
|
|
@ -3254,18 +3254,31 @@ pre.command:before {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-select .dropdown-icon {
|
.dropdown-select .dropdown-select-icon {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 6px;
|
top: 6px;
|
||||||
left: 6px;
|
left: 6px;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-select .dropdown-icon.none-icon {
|
.dropdown-select .dropdown-select-icon.fa {
|
||||||
top: 10px;
|
top: 10px;
|
||||||
left: 8px;
|
left: 8px;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-select .dropdown-select-icon.none-icon {
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-select.has-item .dropdown-select-icon {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-select.has-item .dropdown-select-icon.none-icon {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-select .lookahead-input {
|
.dropdown-select .lookahead-input {
|
||||||
|
@ -3304,4 +3317,24 @@ pre.command:before {
|
||||||
|
|
||||||
.trigger-setup-github-element li.github-org-header {
|
.trigger-setup-github-element li.github-org-header {
|
||||||
padding-left: 6px;
|
padding-left: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slideinout {
|
||||||
|
-webkit-transition:0.5s all;
|
||||||
|
transition:0.5s linear all;
|
||||||
|
opacity: 1;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
height: 100px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slideinout.ng-hide {
|
||||||
|
opacity: 0;
|
||||||
|
height: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slideinout.ng-hide-add, .slideinout.ng-hide-remove {
|
||||||
|
display: block !important;
|
||||||
}
|
}
|
1
static/directives/dropdown-select-icon.html
Normal file
1
static/directives/dropdown-select-icon.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<ng-transclude>
|
1
static/directives/dropdown-select-menu.html
Normal file
1
static/directives/dropdown-select-menu.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<ul class="dropdown-menu" ng-transclude></ul>
|
13
static/directives/dropdown-select.html
Normal file
13
static/directives/dropdown-select.html
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<div class="dropdown-select-element" ng-class="selectedItem ? 'has-item' : ''">
|
||||||
|
<div class="current-item">
|
||||||
|
<div class="dropdown-select-icon-transclude"></div>
|
||||||
|
<input type="text" class="lookahead-input form-control" placeholder="{{ placeholder }}"></input>
|
||||||
|
</div>
|
||||||
|
<div class="dropdown">
|
||||||
|
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">
|
||||||
|
<span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<div class="dropdown-select-menu-transclude"></div>
|
||||||
|
</div>
|
||||||
|
<div class="transcluded" ng-transclude>
|
||||||
|
</div>
|
|
@ -5,26 +5,53 @@
|
||||||
</div>
|
</div>
|
||||||
<div ng-show="!loading">
|
<div ng-show="!loading">
|
||||||
<div style="margin-bottom: 18px">Please choose the GitHub repository that will trigger the build:</div>
|
<div style="margin-bottom: 18px">Please choose the GitHub repository that will trigger the build:</div>
|
||||||
|
|
||||||
|
<!-- Repository select -->
|
||||||
|
<div class="dropdown-select" placeholder="'Select a repository'" selected-item="currentRepo"
|
||||||
|
lookahead-items="repoLookahead">
|
||||||
|
<!-- Icons -->
|
||||||
|
<i class="dropdown-select-icon none-icon fa fa-github fa-lg"></i>
|
||||||
|
<img class="dropdown-select-icon github-org-icon" ng-src="{{ currentRepo.avatar_url ? currentRepo.avatar_url : '//www.gravatar.com/avatar/' }}">
|
||||||
|
|
||||||
|
<!-- Dropdown menu -->
|
||||||
|
<ul class="dropdown-select-menu" role="menu">
|
||||||
|
<li ng-repeat-start="org in orgs" role="presentation" class="dropdown-header github-org-header">
|
||||||
|
<img ng-src="{{ org.info.avatar_url }}" class="github-org-icon">{{ org.info.name }}
|
||||||
|
</li>
|
||||||
|
<li ng-repeat="repo in org.repos" class="github-repo-listing">
|
||||||
|
<a href="javascript:void(0)" ng-click="selectRepo(repo, org)"><i class="fa fa-github fa-lg"></i> {{ repo }}</a>
|
||||||
|
</li>
|
||||||
|
<li role="presentation" class="divider" ng-repeat-end ng-show="$index < orgs.length - 1"></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="dropdown-select">
|
<!-- Dockerfile folder select -->
|
||||||
<div class="current-item">
|
<div class="slideinout" ng-show="currentRepo">
|
||||||
<i ng-show="!currentRepo" class="fa fa-github fa-lg dropdown-icon none-icon"></i>
|
<div style="margin-top: 10px">Dockerfile Location:</div>
|
||||||
<img ng-show="currentRepo" class="dropdown-icon github-org-icon" ng-src="{{ currentRepo.avatar_url ? currentRepo.avatar_url : '//www.gravatar.com/avatar/' }}">
|
<div class="dropdown-select" placeholder="'(Repository Root)'" selected-item="currentLocation"
|
||||||
<input type="text" class="lookahead-input form-control" placeholder="Select a Repository"></input>
|
lookahead-items="locations">
|
||||||
|
<!-- Icons -->
|
||||||
|
<i class="dropdown-select-icon none-icon fa fa-folder-o fa-lg"></i>
|
||||||
|
<i class="dropdown-select-icon fa fa-folder fa-lg"></i>
|
||||||
|
|
||||||
|
<!-- Dropdown menu -->
|
||||||
|
<ul class="dropdown-select-menu" role="menu">
|
||||||
|
<li ng-repeat="location in locations">
|
||||||
|
<a href="javascript:void(0)" ng-click="setLocation(location)" ng-if="!location"><i class="fa fa-github fa-lg"></i> Repository Root</a>
|
||||||
|
<a href="javascript:void(0)" ng-click="setLocation(location)" ng-if="location"><i class="fa fa-folder fa-lg"></i> {{ location }}</a>
|
||||||
|
</li>
|
||||||
|
<li class="dropdown-header" role="presentation" ng-show="!locations.length">No Dockerfiles found in repository</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown">
|
|
||||||
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">
|
<div class="quay-spinner" ng-show="!locations && !locationError"></div>
|
||||||
<span class="caret"></span>
|
<div class="alert alert-warning" ng-show="locations && !locations.length">
|
||||||
</button>
|
Warning: No Dockerfiles were found in {{ currentRepo.repo }}
|
||||||
<ul class="dropdown-menu pull-right" role="menu">
|
</div>
|
||||||
<li ng-repeat-start="org in orgs" role="presentation" class="dropdown-header github-org-header">
|
<div class="alert alert-warning" ng-show="locationError">
|
||||||
<img ng-src="{{ org.info.avatar_url }}" class="github-org-icon">{{ org.info.name }}
|
{{ locationError }}
|
||||||
</li>
|
|
||||||
<li ng-repeat="repo in org.repos" class="gtihub-repo-listing">
|
|
||||||
<a href="javascript:void(0)" ng-click="selectRepo(repo, org)"><i class="fa fa-github fa-lg"></i> {{ repo }}</a>
|
|
||||||
</li>
|
|
||||||
<li role="presentation" class="divider" ng-repeat-end ng-show="$index < orgs.length - 1"></li>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
241
static/js/app.js
241
static/js/app.js
|
@ -102,7 +102,7 @@ function getMarkedDown(string) {
|
||||||
return Markdown.getSanitizingConverter().makeHtml(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;
|
cfpLoadingBarProvider.includeSpinner = false;
|
||||||
|
|
||||||
$provide.factory('UtilService', ['$sanitize', function($sanitize) {
|
$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 () {
|
quayApp.directive('triggerSetupGithub', function () {
|
||||||
var directiveDefinitionObject = {
|
var directiveDefinitionObject = {
|
||||||
priority: 0,
|
priority: 0,
|
||||||
|
@ -2558,48 +2691,86 @@ quayApp.directive('triggerSetupGithub', function () {
|
||||||
controller: function($scope, $element, ApiService) {
|
controller: function($scope, $element, ApiService) {
|
||||||
$scope.setupReady = false;
|
$scope.setupReady = false;
|
||||||
$scope.loading = true;
|
$scope.loading = true;
|
||||||
|
|
||||||
var input = $($element).find('.lookahead-input');
|
$scope.setLocation = function(location) {
|
||||||
|
$scope.currentLocation = location;
|
||||||
$scope.clearSelectedRepo = function() {
|
$scope.trigger['config']['subdir'] = location || '';
|
||||||
$scope.currentRepo = null;
|
|
||||||
$scope.trigger.$ready = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.selectRepo = function(repo, org) {
|
$scope.selectRepo = function(repo, org) {
|
||||||
$(input).val(repo);
|
|
||||||
$scope.selectRepoInternal(repo, org);
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.selectRepoInternal = function(repo, org) {
|
|
||||||
$scope.currentRepo = {
|
$scope.currentRepo = {
|
||||||
'name': repo,
|
'repo': repo,
|
||||||
'avatar_url': org['info']['avatar_url']
|
'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 = [];
|
var repos = [];
|
||||||
for (var i = 0; i < $scope.orgs.length; ++i) {
|
for (var i = 0; i < $scope.orgs.length; ++i) {
|
||||||
var org = $scope.orgs[i];
|
var org = $scope.orgs[i];
|
||||||
var orepos = org['repos'];
|
var orepos = org['repos'];
|
||||||
for (var j = 0; j < orepos.length; ++j) {
|
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({
|
$scope.repoLookahead = repos;
|
||||||
name: 'repos-' + $scope.trigger.id,
|
|
||||||
local: repos,
|
|
||||||
template: function (datum) {
|
|
||||||
template = datum['name'];
|
|
||||||
return template;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var loadSources = function() {
|
var loadSources = function() {
|
||||||
|
@ -2617,16 +2788,8 @@ quayApp.directive('triggerSetupGithub', function () {
|
||||||
|
|
||||||
loadSources();
|
loadSources();
|
||||||
|
|
||||||
$(input).on('input', function(e) {
|
$scope.$watch('currentRepo', function(repo) {
|
||||||
$scope.$apply(function() {
|
$scope.selectRepoInternal(repo);
|
||||||
$scope.clearSelectedRepo();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$(input).on('typeahead:selected', function(e, datum) {
|
|
||||||
$scope.$apply(function() {
|
|
||||||
$scope.selectRepoInternal(datum.repo, datum.org);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"></script>
|
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"></script>
|
||||||
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular-route.min.js"></script>
|
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular-route.min.js"></script>
|
||||||
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular-sanitize.min.js"></script>
|
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular-sanitize.min.js"></script>
|
||||||
|
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular-animate.min.js"></script>
|
||||||
|
|
||||||
<script src="//cdn.jsdelivr.net/g/bootbox@4.1.0,underscorejs@1.5.2,restangular@1.2.0"></script>
|
<script src="//cdn.jsdelivr.net/g/bootbox@4.1.0,underscorejs@1.5.2,restangular@1.2.0"></script>
|
||||||
|
|
||||||
|
|
Reference in a new issue