mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-12-27 02:39:53 +01:00
(refs #1286) Update collaborators setting form
This commit is contained in:
@@ -108,12 +108,18 @@ trait IndexControllerBase extends ControllerBase {
|
||||
*/
|
||||
get("/_user/proposals")(usersOnly {
|
||||
contentType = formats("json")
|
||||
val user = params("user").toBoolean
|
||||
val group = params("group").toBoolean
|
||||
org.json4s.jackson.Serialization.write(
|
||||
Map("options" -> (if(params.get("userOnly").isDefined) {
|
||||
getAllUsers(false).filter(!_.isGroupAccount).map { t => (t.userName, t.isGroupAccount) }.toArray
|
||||
} else {
|
||||
getAllUsers(false).map { t => (t.userName, t.isGroupAccount) }.toArray
|
||||
}).map { case (userName, groupAccount) => userName + ":" + groupAccount })
|
||||
Map("options" -> (
|
||||
getAllUsers(false)
|
||||
.withFilter { t => (user, group) match {
|
||||
case (true, true) => true
|
||||
case (true, false) => !t.isGroupAccount
|
||||
case (false, true) => t.isGroupAccount
|
||||
case (false, false) => false
|
||||
}}.map { t => t.userName }
|
||||
))
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
@@ -42,9 +42,9 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
||||
"repositoryName" -> trim(label("Repository Name" , text(required, maxlength(40), identifier, renameRepositoryName))),
|
||||
"description" -> trim(label("Description" , optional(text()))),
|
||||
"isPrivate" -> trim(label("Repository Type" , boolean())),
|
||||
"issuesOption" -> trim(label("Issues Option" , text(required))), // TODO enum check
|
||||
"issuesOption" -> trim(label("Issues Option" , text(required, featureOption))),
|
||||
"externalIssuesUrl" -> trim(label("External Issues URL", optional(text(maxlength(200))))),
|
||||
"wikiOption" -> trim(label("Wiki Option" , text(required))), // TODO enum check
|
||||
"wikiOption" -> trim(label("Wiki Option" , text(required, featureOption))),
|
||||
"externalWikiUrl" -> trim(label("External Wiki URL" , optional(text(maxlength(200))))),
|
||||
"allowFork" -> trim(label("Allow Forking" , boolean()))
|
||||
)(OptionsForm.apply)
|
||||
@@ -56,12 +56,12 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
||||
"defaultBranch" -> trim(label("Default Branch" , text(required, maxlength(100))))
|
||||
)(DefaultBranchForm.apply)
|
||||
|
||||
// for collaborator addition
|
||||
case class CollaboratorForm(userName: String)
|
||||
|
||||
val collaboratorForm = mapping(
|
||||
"userName" -> trim(label("Username", text(required, collaborator)))
|
||||
)(CollaboratorForm.apply)
|
||||
// // for collaborator addition
|
||||
// case class CollaboratorForm(userName: String)
|
||||
//
|
||||
// val collaboratorForm = mapping(
|
||||
// "userName" -> trim(label("Username", text(required, collaborator)))
|
||||
// )(CollaboratorForm.apply)
|
||||
|
||||
// for web hook url addition
|
||||
case class WebHookForm(url: String, events: Set[WebHook.Event], ctype: WebHookContentType, token: Option[String])
|
||||
@@ -178,7 +178,7 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
||||
post("/:owner/:repository/settings/collaborators")(ownerOnly { repository =>
|
||||
val collaborators = params("collaborators")
|
||||
removeCollaborators(repository.owner, repository.name)
|
||||
collaborators.split(",").map { collaborator =>
|
||||
collaborators.split(",").withFilter(_.nonEmpty).map { collaborator =>
|
||||
val userName :: permission :: Nil = collaborator.split(":").toList
|
||||
addCollaborator(repository.owner, repository.name, userName, permission)
|
||||
}
|
||||
@@ -384,20 +384,20 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides Constraint to validate the collaborator name.
|
||||
*/
|
||||
private def collaborator: Constraint = new Constraint(){
|
||||
override def validate(name: String, value: String, messages: Messages): Option[String] =
|
||||
getAccountByUserName(value) match {
|
||||
case None => Some("User does not exist.")
|
||||
// case Some(x) if(x.isGroupAccount)
|
||||
// => Some("User does not exist.")
|
||||
case Some(x) if(x.userName == params("owner") || getCollaborators(params("owner"), params("repository")).contains(x.userName))
|
||||
=> Some(value + " is repository owner.") // TODO also group members?
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
// /**
|
||||
// * Provides Constraint to validate the collaborator name.
|
||||
// */
|
||||
// private def collaborator: Constraint = new Constraint(){
|
||||
// override def validate(name: String, value: String, messages: Messages): Option[String] =
|
||||
// getAccountByUserName(value) match {
|
||||
// case None => Some("User does not exist.")
|
||||
//// case Some(x) if(x.isGroupAccount)
|
||||
//// => Some("User does not exist.")
|
||||
// case Some(x) if(x.userName == params("owner") || getCollaborators(params("owner"), params("repository")).contains(x.userName))
|
||||
// => Some(value + " is repository owner.") // TODO also group members?
|
||||
// case _ => None
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* Duplicate check for the rename repository name.
|
||||
@@ -411,6 +411,15 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private def featureOption: Constraint = new Constraint(){
|
||||
override def validate(name: String, value: String, params: Map[String, String], messages: Messages): Option[String] =
|
||||
if(Seq("DISABLE", "PRIVATE", "PUBLIC").contains(value)) None else Some("Option is invalid.")
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Provides Constraint to validate the repository transfer user.
|
||||
*/
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<label class="strong">Members</label>
|
||||
<ul id="member-list" class="collaborator">
|
||||
</ul>
|
||||
@gitbucket.core.helper.html.account("memberName", 200)
|
||||
@gitbucket.core.helper.html.account("memberName", 200, true, false)
|
||||
<input type="button" class="btn btn-default" value="Add" id="addMember"/>
|
||||
<input type="hidden" id="members" name="members" value="@members.map(member => member.userName + ":" + member.isManager).mkString(",")"/>
|
||||
<div>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<label class="strong">Members</label>
|
||||
<ul id="member-list" class="collaborator">
|
||||
</ul>
|
||||
@gitbucket.core.helper.html.account("memberName", 200)
|
||||
@gitbucket.core.helper.html.account("memberName", 200, true, false)
|
||||
<input type="button" class="btn btn-default" value="Add" id="addMember"/>
|
||||
<input type="hidden" id="members" name="members" value="@members.map(member => member.userName + ":" + member.isManager).mkString(",")"/>
|
||||
<div>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
@(id: String, width: Int, userOnly: Boolean = true)(implicit context: gitbucket.core.controller.Context)
|
||||
@(id: String, width: Int, user: Boolean, group: Boolean)(implicit context: gitbucket.core.controller.Context)
|
||||
<span style="margin-right: 0px;">
|
||||
<input type="text" name="@id" id="@id" class="form-control" autocomplete="off" style="width: @{width}px; margin-bottom: 0px; display: inline; vertical-align: middle;"/>
|
||||
</span>
|
||||
<script>
|
||||
$(function(){
|
||||
$('#@id').typeahead({
|
||||
highlighter: function(item) {
|
||||
var x = item.split(':');
|
||||
return $('<div><strong>' + x[0] + '</strong>' + (x[1] == 'true' ? ' (group)' : '') + '</div>');
|
||||
},
|
||||
updater: function (item) {
|
||||
return item.split(':')[0];
|
||||
},
|
||||
// highlighter: function(item) {
|
||||
// var x = item.split(':');
|
||||
// return $('<div><strong>' + x[0] + '</strong>' + (x[1] == 'true' ? ' (group)' : '') + '</div>');
|
||||
// },
|
||||
// updater: function (item) {
|
||||
// return item.split(':')[0];
|
||||
// },
|
||||
source: function (query, process) {
|
||||
return $.get('@context.path/_user/proposals@if(userOnly){?userOnly}', { query: query },
|
||||
return $.get('@context.path/_user/proposals', { query: query, user: @user, group: @group },
|
||||
function (data) {
|
||||
return process(data.options);
|
||||
});
|
||||
|
||||
@@ -6,17 +6,35 @@
|
||||
@gitbucket.core.html.main("Settings", Some(repository)){
|
||||
@gitbucket.core.html.menu("settings", repository){
|
||||
@gitbucket.core.settings.html.menu("collaborators", repository){
|
||||
<h3>Manage Collaborators</h3>
|
||||
<form id="form" method="post" action="@helpers.url(repository)/settings/collaborators">
|
||||
<ul id="collaborator-list" class="collaborator">
|
||||
</ul>
|
||||
@gitbucket.core.helper.html.account("userName", 200, false)
|
||||
<input type="button" class="btn btn-default" value="Add" id="addCollaborator"/>
|
||||
<input type="hidden" id="collaborators" name="collaborators" value="@collaborators.map(x => x._1.userName + ":" + x._1.permission).mkString(",")"/>
|
||||
<div>
|
||||
<span class="error" id="error-collaborators"></span>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading strong">Collaborators</div>
|
||||
<div class="panel-body">
|
||||
<ul id="collaborator-list" class="collaborator">
|
||||
</ul>
|
||||
@gitbucket.core.helper.html.account("userName-collaborator", 200, true, false)
|
||||
<input type="button" class="btn btn-default add" value="Add" id="addCollaborator"/>
|
||||
<div>
|
||||
<span class="error" id="error-collaborator"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading strong">Groups</div>
|
||||
<div class="panel-body">
|
||||
<ul id="group-list" class="collaborator">
|
||||
</ul>
|
||||
@gitbucket.core.helper.html.account("userName-group", 200, false, true)
|
||||
<input type="button" class="btn btn-default add" value="Add" id="addGroup"/>
|
||||
<div>
|
||||
<span class="error" id="error-group"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="align-right" style="margin-top: 20px;">
|
||||
<input type="hidden" id="collaborators" name="collaborators" />
|
||||
<input type="submit" class="btn btn-success" value="Apply changes"/>
|
||||
</div>
|
||||
</form>
|
||||
@@ -26,24 +44,32 @@
|
||||
<script>
|
||||
$(function(){
|
||||
$('input[type=submit]').click(function(){
|
||||
updateCollaborators();
|
||||
updateValues();
|
||||
});
|
||||
|
||||
$('#addCollaborator').click(function(){
|
||||
$('#error-collaborators').text('');
|
||||
var userName = $('#userName').val();
|
||||
$('.add').click(function(){
|
||||
var id = $(this).attr('id') == 'addCollaborator' ? 'collaborator' : 'group';
|
||||
|
||||
$('#error-' + id).text('');
|
||||
var userName = $('#userName-' + id).val();
|
||||
|
||||
// check empty
|
||||
if($.trim(userName) == ''){
|
||||
return false;
|
||||
}
|
||||
|
||||
// check owner
|
||||
var owner = '@repository.owner' == userName
|
||||
if(owner){
|
||||
$('#error-' + id).text('User is owner of this repository.');
|
||||
return false;
|
||||
}
|
||||
// check duplication
|
||||
var exists = $('#collaborator-list li').filter(function(){
|
||||
var exists = $('#' + id + '-list li').filter(function(){
|
||||
return $(this).data('name') == userName;
|
||||
}).length > 0;
|
||||
if(exists){
|
||||
$('#error-collaborators').text('User has been already added.');
|
||||
$('#error-' + id).text('User has been already added.');
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -51,9 +77,9 @@ $(function(){
|
||||
$.post('@context.path/_user/existence', { 'userName': userName },
|
||||
function(data, status){
|
||||
if(data != ''){
|
||||
addCollaboratorHTML(userName, '@Permission.ADMIN.name', data == 'group');
|
||||
addListHTML(userName, '@Permission.ADMIN.name', '#' + id + '-list');
|
||||
} else {
|
||||
$('#error-collaborators').text('User does not exist.');
|
||||
$('#error-' + id).text('User does not exist.');
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -63,15 +89,15 @@ $(function(){
|
||||
});
|
||||
|
||||
// Don't submit form by ENTER key
|
||||
$('#userName').keypress(function(e){
|
||||
$('#userName-collaborator, #userName-group').keypress(function(e){
|
||||
return !(e.keyCode == 13);
|
||||
});
|
||||
|
||||
@collaborators.map { case (collaborator, isGroup) =>
|
||||
addCollaboratorHTML('@collaborator.collaboratorName', '@collaborator.permission', @isGroup);
|
||||
addListHTML('@collaborator.collaboratorName', '@collaborator.permission', @if(isGroup){'#group-list'}else{'#collaborator-list'});
|
||||
}
|
||||
|
||||
function addCollaboratorHTML(userName, permission, isGroup){
|
||||
function addListHTML(userName, permission, id){
|
||||
var adminButton = $('<label class="btn btn-default btn-mini"><input type="radio" value="@Permission.ADMIN.name" name="' + userName + '">Admin</label>');
|
||||
if(permission == '@Permission.ADMIN.name'){
|
||||
adminButton.addClass('active');
|
||||
@@ -85,24 +111,29 @@ $(function(){
|
||||
readButton.addClass('active');
|
||||
}
|
||||
|
||||
$('#collaborator-list').append($('<li>')
|
||||
$(id).append($('<li>')
|
||||
.data('name', userName)
|
||||
.append($('<div class="btn-group permission" data-toggle="buttons">')
|
||||
.append(adminButton)
|
||||
.append(writeButton)
|
||||
.append(readButton))
|
||||
.append(' ')
|
||||
.append($('<a>').attr('href', '@context.path/' + userName).text(userName))
|
||||
.append(isGroup ? ' (group)' : '')
|
||||
.append($('<a target="_blank">').attr('href', '@context.path/' + userName).text(userName))
|
||||
.append($('<a href="#" class="remove pull-right">(remove)</a>')));
|
||||
}
|
||||
|
||||
function updateCollaborators(){
|
||||
function updateValues(){
|
||||
var collaborators = $('#collaborator-list li').map(function(i, e){
|
||||
var userName = $(e).data('name');
|
||||
return userName + ':' + $(e).find('label.active input[type=radio]').attr('value');
|
||||
}).get().join(',');
|
||||
$('#collaborators').val(collaborators);
|
||||
|
||||
var groups = $('#group-list li').map(function(i, e){
|
||||
var userName = $(e).data('name');
|
||||
return userName + ':' + $(e).find('label.active input[type=radio]').attr('value');
|
||||
}).get().join(',');
|
||||
|
||||
$('#collaborators').val(collaborators + ',' + groups);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -13,7 +13,7 @@
|
||||
<div>
|
||||
Transfer this repo to another user or to group.
|
||||
<div class="pull-right">
|
||||
@gitbucket.core.helper.html.account("newOwner", 200)
|
||||
@gitbucket.core.helper.html.account("newOwner", 200, true, true)
|
||||
<input type="submit" class="btn btn-danger" value="Transfer"/>
|
||||
<div>
|
||||
<span id="error-newOwner" class="error"></span>
|
||||
|
||||
Reference in New Issue
Block a user