Merge branch 'master' of https://bitbucket.org/yackob03/quay
This commit is contained in:
commit
d41f651a38
11 changed files with 241 additions and 51 deletions
|
@ -1658,7 +1658,7 @@ def get_user_robots():
|
||||||
@app.route('/api/organization/<orgname>/robots', methods=['GET'])
|
@app.route('/api/organization/<orgname>/robots', methods=['GET'])
|
||||||
@api_login_required
|
@api_login_required
|
||||||
def get_org_robots(orgname):
|
def get_org_robots(orgname):
|
||||||
permission = AdministerOrganizationPermission(orgname)
|
permission = OrganizationMemberPermission(orgname)
|
||||||
if permission.can():
|
if permission.can():
|
||||||
robots = model.list_entity_robots(orgname)
|
robots = model.list_entity_robots(orgname)
|
||||||
return jsonify({
|
return jsonify({
|
||||||
|
|
|
@ -3,6 +3,39 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.entity-search-element input {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entity-search-element .twitter-typeahead {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entity-search-element .dropdown {
|
||||||
|
vertical-align: middle;
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu i.fa {
|
||||||
|
margin-right: 6px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu .new-action i.fa {
|
||||||
|
atext-shadow: 2px 2px 7px #5cb85c, 2px 2px 7px #5cb85c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu .new-action i.fa:after {
|
||||||
|
content: "+";
|
||||||
|
color: #5cb85c;
|
||||||
|
position: absolute;
|
||||||
|
left: -14px;
|
||||||
|
top: -2px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 115%;
|
||||||
|
}
|
||||||
|
|
||||||
#input-box {
|
#input-box {
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
<i class="fa fa-user" ng-show="!team && !isrobot" title="User" bs-tooltip="tooltip.title" data-container="body"></i>
|
<i class="fa fa-user" ng-show="!team && !isrobot" title="User" bs-tooltip="tooltip.title" data-container="body"></i>
|
||||||
<i class="fa fa-wrench" ng-show="!team && isrobot" title="Robot Account" bs-tooltip="tooltip.title" data-container="body"></i>
|
<i class="fa fa-wrench" ng-show="!team && isrobot" title="Robot Account" bs-tooltip="tooltip.title" data-container="body"></i>
|
||||||
<i class="fa fa-group" ng-show="team" title="Team" bs-tooltip="tooltip.title" data-container="body"></i>
|
<i class="fa fa-group" ng-show="team" title="Team" bs-tooltip="tooltip.title" data-container="body"></i>
|
||||||
<span ng-show="team"><a href="/organization/{{ orgname }}/teams/{{ team }}">{{team}}</a></span>
|
<span ng-show="team && getIsAdmin(orgname)"><a href="/organization/{{ orgname }}/teams/{{ team }}">{{team}}</a></span>
|
||||||
|
<span ng-show="team && !getIsAdmin(orgname)">{{team}}</span>
|
||||||
<span ng-show="isrobot" class="prefix">{{getPrefix(name)}}</span><span>{{getShortenedName(name)}}</span>
|
<span ng-show="isrobot" class="prefix">{{getPrefix(name)}}</span><span>{{getShortenedName(name)}}</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -1 +1,40 @@
|
||||||
<input class="entity-search-control form-control">
|
<span class="entity-search-element"><input class="entity-search-control form-control">
|
||||||
|
<div class="dropdown">
|
||||||
|
<button class="btn btn-default dropdown-toggle" type="button" id="entityDropdownMenu" data-toggle="dropdown"
|
||||||
|
ng-click="lazyLoad()">
|
||||||
|
<span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" role="menu" aria-labelledby="entityDropdownMenu">
|
||||||
|
<li ng-show="lazyLoading"><i class="fa fa-spinner"></i></li>
|
||||||
|
|
||||||
|
<li role="presentation" ng-repeat="team in teams" ng-show="!lazyLoading"
|
||||||
|
ng-click="setEntity(team.name, 'team', false)">
|
||||||
|
<a role="menuitem" tabindex="-1" href="javascript:void(0)">
|
||||||
|
<i class="fa fa-group"></i> <span>{{ team.name }}</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li role="presentation" class="divider" ng-show="!lazyLoading && teams && (isAdmin || robots)"></li>
|
||||||
|
|
||||||
|
<li role="presentation" ng-repeat="robot in robots" ng-show="!lazyLoading">
|
||||||
|
<a role="menuitem" tabindex="-1" href="javascript:void(0)" ng-click="setEntity(robot.name, 'user', true)">
|
||||||
|
<i class="fa fa-wrench"></i> <span>{{ robot.name }}</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li role="presentation" class="divider" ng-show="!lazyLoading && robots && isAdmin"></li>
|
||||||
|
|
||||||
|
<li role="presentation" ng-show="includeTeams && isOrganization && !lazyLoading && isAdmin">
|
||||||
|
<a role="menuitem" class="new-action" tabindex="-1" href="javascript:void(0)" ng-click="createTeam()">
|
||||||
|
<i class="fa fa-group"></i> Create team
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li role="presentation" ng-show="!lazyLoading && isAdmin">
|
||||||
|
<a role="menuitem" class="new-action" tabindex="-1" href="javascript:void(0)" ng-click="createRobot()">
|
||||||
|
<i class="fa fa-wrench"></i>
|
||||||
|
Create robot account
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
<div class="container" ng-show="!loading">
|
<div class="container" ng-show="!loading">
|
||||||
<div class="side-controls">
|
<div class="side-controls">
|
||||||
<span class="popup-input-button" pattern="'^[a-zA-Z][a-zA-Z0-9]+$'" placeholder="'Robot Account Name'"
|
<span class="popup-input-button" pattern="ROBOT_PATTERN" placeholder="'Robot Account Name'"
|
||||||
submitted="createRobot(value)">
|
submitted="createRobot(value)">
|
||||||
<i class="fa fa-wrench"></i> Create Robot Account
|
<i class="fa fa-wrench"></i> Create Robot Account
|
||||||
</span>
|
</span>
|
||||||
|
|
168
static/js/app.js
168
static/js/app.js
|
@ -1,3 +1,6 @@
|
||||||
|
var TEAM_PATTERN = '^[a-zA-Z][a-zA-Z0-9]+$';
|
||||||
|
var ROBOT_PATTERN = '^[a-zA-Z][a-zA-Z0-9]+$';
|
||||||
|
|
||||||
function getFirstTextLine(commentString) {
|
function getFirstTextLine(commentString) {
|
||||||
if (!commentString) { return ''; }
|
if (!commentString) { return ''; }
|
||||||
|
|
||||||
|
@ -31,6 +34,45 @@ function getFirstTextLine(commentString) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createRobotAccount(Restangular, is_org, orgname, name, callback) {
|
||||||
|
var url = is_org ? getRestUrl('organization', orgname, 'robots', name) :
|
||||||
|
getRestUrl('user/robots', name);
|
||||||
|
var createRobot = Restangular.one(url);
|
||||||
|
createRobot.customPUT().then(callback, function(resp) {
|
||||||
|
bootbox.dialog({
|
||||||
|
"message": resp.data ? resp.data : 'The robot account could not be created',
|
||||||
|
"title": "Cannot create robot account",
|
||||||
|
"buttons": {
|
||||||
|
"close": {
|
||||||
|
"label": "Close",
|
||||||
|
"className": "btn-primary"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function createOrganizationTeam(Restangular, orgname, teamname, callback) {
|
||||||
|
var createTeam = Restangular.one(getRestUrl('organization', orgname, 'team', teamname));
|
||||||
|
var data = {
|
||||||
|
'name': teamname,
|
||||||
|
'role': 'member'
|
||||||
|
};
|
||||||
|
|
||||||
|
createTeam.customPOST(data).then(callback, function() {
|
||||||
|
bootbox.dialog({
|
||||||
|
"message": resp.data ? resp.data : 'The team could not be created',
|
||||||
|
"title": "Cannot create team",
|
||||||
|
"buttons": {
|
||||||
|
"close": {
|
||||||
|
"label": "Close",
|
||||||
|
"className": "btn-primary"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function getRestUrl(args) {
|
function getRestUrl(args) {
|
||||||
var url = '';
|
var url = '';
|
||||||
for (var i = 0; i < arguments.length; ++i) {
|
for (var i = 0; i < arguments.length; ++i) {
|
||||||
|
@ -95,6 +137,19 @@ quayApp = angular.module('quay', ['ngRoute', 'restangular', 'angularMoment', 'an
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
userService.isNamespaceAdmin = function(namespace) {
|
||||||
|
if (namespace == userResponse.username) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var org = userService.getOrganization(namespace);
|
||||||
|
if (!org) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return org.is_org_admin;
|
||||||
|
};
|
||||||
|
|
||||||
userService.currentUser = function() {
|
userService.currentUser = function() {
|
||||||
return userResponse;
|
return userResponse;
|
||||||
};
|
};
|
||||||
|
@ -476,7 +531,11 @@ quayApp.directive('entityReference', function () {
|
||||||
'team': '=team',
|
'team': '=team',
|
||||||
'isrobot': '=isrobot'
|
'isrobot': '=isrobot'
|
||||||
},
|
},
|
||||||
controller: function($scope, $element) {
|
controller: function($scope, $element, UserService) {
|
||||||
|
$scope.getIsAdmin = function(orgname) {
|
||||||
|
return UserService.isNamespaceAdmin(orgname);
|
||||||
|
};
|
||||||
|
|
||||||
$scope.getPrefix = function(name) {
|
$scope.getPrefix = function(name) {
|
||||||
if (!name) { return ''; }
|
if (!name) { return ''; }
|
||||||
var plus = name.indexOf('+');
|
var plus = name.indexOf('+');
|
||||||
|
@ -952,6 +1011,7 @@ quayApp.directive('robotsManager', function () {
|
||||||
'user': '=user'
|
'user': '=user'
|
||||||
},
|
},
|
||||||
controller: function($scope, $element, Restangular) {
|
controller: function($scope, $element, Restangular) {
|
||||||
|
$scope.ROBOT_PATTERN = ROBOT_PATTERN;
|
||||||
$scope.robots = null;
|
$scope.robots = null;
|
||||||
$scope.loading = false;
|
$scope.loading = false;
|
||||||
$scope.shownRobot = null;
|
$scope.shownRobot = null;
|
||||||
|
@ -975,22 +1035,9 @@ quayApp.directive('robotsManager', function () {
|
||||||
$scope.createRobot = function(name) {
|
$scope.createRobot = function(name) {
|
||||||
if (!name) { return; }
|
if (!name) { return; }
|
||||||
|
|
||||||
var url = $scope.organization ? getRestUrl('organization', $scope.organization.name, 'robots', name) :
|
createRobotAccount(Restangular, !!$scope.organization, $scope.organization ? $scope.organization.name : '', name,
|
||||||
getRestUrl('user/robots', name);
|
function(created) {
|
||||||
var createRobot = Restangular.one(url);
|
$scope.robots.push(created);
|
||||||
createRobot.customPUT().then(function(resp) {
|
|
||||||
$scope.robots.push(resp);
|
|
||||||
}, function(resp) {
|
|
||||||
bootbox.dialog({
|
|
||||||
"message": resp.data ? resp.data : 'The robot account could not be created',
|
|
||||||
"title": "Cannot create robot account",
|
|
||||||
"buttons": {
|
|
||||||
"close": {
|
|
||||||
"label": "Close",
|
|
||||||
"className": "btn-primary"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1265,14 +1312,93 @@ quayApp.directive('entitySearch', function () {
|
||||||
'namespace': '=namespace',
|
'namespace': '=namespace',
|
||||||
'inputTitle': '=inputTitle',
|
'inputTitle': '=inputTitle',
|
||||||
'entitySelected': '=entitySelected',
|
'entitySelected': '=entitySelected',
|
||||||
'includeTeams': '=includeTeams'
|
'includeTeams': '=includeTeams',
|
||||||
|
'isOrganization': '=isOrganization'
|
||||||
},
|
},
|
||||||
controller: function($scope, $element) {
|
controller: function($scope, $element, Restangular, UserService) {
|
||||||
|
$scope.lazyLoading = true;
|
||||||
|
$scope.isAdmin = false;
|
||||||
|
|
||||||
|
$scope.lazyLoad = function() {
|
||||||
|
if (!$scope.namespace || !$scope.lazyLoading) { return; }
|
||||||
|
|
||||||
|
$scope.isAdmin = UserService.isNamespaceAdmin($scope.namespace);
|
||||||
|
|
||||||
|
if ($scope.isOrganization && $scope.includeTeams) {
|
||||||
|
var url = getRestUrl('organization', $scope.namespace);
|
||||||
|
var getOrganization = Restangular.one(url);
|
||||||
|
getOrganization.customGET().then(function(resp) {
|
||||||
|
$scope.teams = resp.teams;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var url = $scope.isOrganization ? getRestUrl('organization', $scope.namespace, 'robots') : 'user/robots';
|
||||||
|
var getRobots = Restangular.one(url);
|
||||||
|
getRobots.customGET().then(function(resp) {
|
||||||
|
$scope.robots = resp.robots;
|
||||||
|
$scope.lazyLoading = false;
|
||||||
|
}, function() {
|
||||||
|
$scope.lazyLoading = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.createTeam = function() {
|
||||||
|
if (!$scope.isAdmin) { return; }
|
||||||
|
|
||||||
|
bootbox.prompt('Enter the name of the new team', function(teamname) {
|
||||||
|
if (!teamname) { return; }
|
||||||
|
|
||||||
|
var regex = new RegExp(TEAM_PATTERN);
|
||||||
|
if (!regex.test(teamname)) {
|
||||||
|
bootbox.alert('Invalid team name');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
createOrganizationTeam(Restangular, $scope.namespace, teamname, function(created) {
|
||||||
|
$scope.setEntity(created.name, 'team', false);
|
||||||
|
$scope.teams[teamname] = created;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.createRobot = function() {
|
||||||
|
if (!$scope.isAdmin) { return; }
|
||||||
|
|
||||||
|
bootbox.prompt('Enter the name of the new robot account', function(robotname) {
|
||||||
|
if (!robotname) { return; }
|
||||||
|
|
||||||
|
var regex = new RegExp(ROBOT_PATTERN);
|
||||||
|
if (!regex.test(robotname)) {
|
||||||
|
bootbox.alert('Invalid robot account name');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
createRobotAccount(Restangular, $scope.isOrganization, $scope.namespace, robotname, function(created) {
|
||||||
|
$scope.setEntity(created.name, 'user', true);
|
||||||
|
$scope.robots.push(created);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.setEntity = function(name, kind, is_robot) {
|
||||||
|
var entity = {
|
||||||
|
'name': name,
|
||||||
|
'kind': kind,
|
||||||
|
'is_robot': is_robot
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($scope.is_organization) {
|
||||||
|
entity['is_org_member'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.entitySelected(entity);
|
||||||
|
};
|
||||||
|
|
||||||
if (!$scope.entitySelected) { return; }
|
if (!$scope.entitySelected) { return; }
|
||||||
|
|
||||||
number++;
|
number++;
|
||||||
|
|
||||||
var input = $element[0].firstChild;
|
var input = $element[0].firstChild.firstChild;
|
||||||
$scope.namespace = $scope.namespace || '';
|
$scope.namespace = $scope.namespace || '';
|
||||||
$(input).typeahead({
|
$(input).typeahead({
|
||||||
name: 'entities' + number,
|
name: 'entities' + number,
|
||||||
|
@ -1321,8 +1447,10 @@ quayApp.directive('entitySearch', function () {
|
||||||
|
|
||||||
$(input).on('typeahead:selected', function(e, datum) {
|
$(input).on('typeahead:selected', function(e, datum) {
|
||||||
$(input).typeahead('setQuery', '');
|
$(input).typeahead('setQuery', '');
|
||||||
|
$scope.$apply(function() {
|
||||||
$scope.entitySelected(datum.entity);
|
$scope.entitySelected(datum.entity);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
$scope.$watch('inputTitle', function(title) {
|
$scope.$watch('inputTitle', function(title) {
|
||||||
input.setAttribute('placeholder', title);
|
input.setAttribute('placeholder', title);
|
||||||
|
|
|
@ -418,11 +418,7 @@ function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Need the $scope.apply for both the permission stuff to change and for
|
|
||||||
// the XHR call to be made.
|
|
||||||
$scope.$apply(function() {
|
|
||||||
$scope.addRole(entity.name, 'read', entity.kind);
|
$scope.addRole(entity.name, 'read', entity.kind);
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.deleteRole = function(entityName, kind) {
|
$scope.deleteRole = function(entityName, kind) {
|
||||||
|
@ -1020,6 +1016,7 @@ function OrgViewCtrl($rootScope, $scope, Restangular, $routeParams) {
|
||||||
'html': true
|
'html': true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$scope.TEAM_PATTERN = TEAM_PATTERN;
|
||||||
$rootScope.title = 'Loading...';
|
$rootScope.title = 'Loading...';
|
||||||
|
|
||||||
var orgname = $routeParams.orgname;
|
var orgname = $routeParams.orgname;
|
||||||
|
@ -1071,15 +1068,8 @@ function OrgViewCtrl($rootScope, $scope, Restangular, $routeParams) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var createTeam = Restangular.one(getRestUrl('organization', orgname, 'team', teamname));
|
createOrganizationTeam(Restangular, orgname, teamname, function(created) {
|
||||||
var data = {
|
$scope.organization.teams[teamname] = created;
|
||||||
'name': teamname,
|
|
||||||
'role': 'member'
|
|
||||||
};
|
|
||||||
createTeam.customPOST(data).then(function(resp) {
|
|
||||||
$scope.organization.teams[teamname] = resp;
|
|
||||||
}, function() {
|
|
||||||
$('#cannotChangeTeamModal').modal({});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1206,14 +1196,12 @@ function TeamViewCtrl($rootScope, $scope, Restangular, $routeParams) {
|
||||||
$scope.addNewMember = function(member) {
|
$scope.addNewMember = function(member) {
|
||||||
if ($scope.members[member.name]) { return; }
|
if ($scope.members[member.name]) { return; }
|
||||||
|
|
||||||
$scope.$apply(function() {
|
|
||||||
var addMember = Restangular.one(getRestUrl('organization', $scope.orgname, 'team', teamname, 'members', member.name));
|
var addMember = Restangular.one(getRestUrl('organization', $scope.orgname, 'team', teamname, 'members', member.name));
|
||||||
addMember.customPOST().then(function(resp) {
|
addMember.customPOST().then(function(resp) {
|
||||||
$scope.members[member.name] = resp;
|
$scope.members[member.name] = resp;
|
||||||
}, function() {
|
}, function() {
|
||||||
$('#cannotChangeMembersModal').modal({});
|
$('#cannotChangeMembersModal').modal({});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.removeMember = function(username) {
|
$scope.removeMember = function(username) {
|
||||||
|
|
|
@ -126,7 +126,7 @@
|
||||||
|
|
||||||
<tr ng-repeat="memberInfo in (membersFound | filter:search | limitTo:50)">
|
<tr ng-repeat="memberInfo in (membersFound | filter:search | limitTo:50)">
|
||||||
<td>
|
<td>
|
||||||
<span class="entity-reference" name="memberInfo.username" isrobot="memberInfo.is_robot"></span>
|
<span class="entity-reference" name="memberInfo.username" isrobot="memberInfo.is_robot" isorgadmin="true"></span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="team-link" ng-repeat="team in memberInfo.teams">
|
<span class="team-link" ng-repeat="team in memberInfo.teams">
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<div class="organization-header" organization="organization">
|
<div class="organization-header" organization="organization">
|
||||||
<div class="header-buttons" ng-show="organization.is_admin">
|
<div class="header-buttons" ng-show="organization.is_admin">
|
||||||
|
|
||||||
<span class="popup-input-button" pattern="'^[a-zA-Z][a-zA-Z0-9]+$'" placeholder="'Team Name'"
|
<span class="popup-input-button" pattern="TEAM_PATTERN" placeholder="'Team Name'"
|
||||||
submitted="createTeam(value)">
|
submitted="createTeam(value)">
|
||||||
<i class="fa fa-group"></i> Create Team
|
<i class="fa fa-group"></i> Create Team
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -92,7 +92,7 @@
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" class="admin-search">
|
<td colspan="2" class="admin-search">
|
||||||
<span class="entity-search" namespace="repo.namespace" include-teams="true" input-title="'Add a ' + (repo.is_organization ? 'team or ' : '') + 'user...'" entity-selected="addNewPermission"></span>
|
<span class="entity-search" namespace="repo.namespace" include-teams="true" input-title="'Add a ' + (repo.is_organization ? 'team or ' : '') + 'user...'" entity-selected="addNewPermission" is-organization="repo.is_organization"></span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -32,7 +32,8 @@
|
||||||
|
|
||||||
<tr ng-show="canEditMembers">
|
<tr ng-show="canEditMembers">
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<span class="entity-search" namespace="orgname" include-teams="false" input-title="'Add a user...'" entity-selected="addNewMember"></span>
|
<span class="entity-search" namespace="orgname" include-teams="false" input-title="'Add a user...'"
|
||||||
|
entity-selected="addNewMember" is-organization="true"></span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
Reference in a new issue