diff --git a/src/main/scala/gitbucket/core/controller/IndexController.scala b/src/main/scala/gitbucket/core/controller/IndexController.scala index 0188d34f8..5136a0d10 100644 --- a/src/main/scala/gitbucket/core/controller/IndexController.scala +++ b/src/main/scala/gitbucket/core/controller/IndexController.scala @@ -251,13 +251,22 @@ trait IndexControllerBase extends ControllerBase { } } .map { t => - Map( - "label" -> s"${avatar(t.userName, 16)}@${StringUtil.escapeHtml( - StringUtil.cutTail(t.userName, 25, "...") - )} ${StringUtil - .escapeHtml(StringUtil.cutTail(t.fullName, 25, "..."))}", - "value" -> t.userName - ) + if (t.isGroupAccount) { + Map( + "label" -> s"${avatar(t.userName, 16)} @${StringUtil.escapeHtml( + StringUtil.cutTail(t.userName, 25, "...") + )}", + "value" -> t.userName + ) + } else { + Map( + "label" -> s"${avatar(t.userName, 16)} @${StringUtil.escapeHtml( + StringUtil.cutTail(t.userName, 25, "...") + )} (${StringUtil + .escapeHtml(StringUtil.cutTail(t.fullName, 25, "..."))})", + "value" -> t.userName + ) + } } ) ) diff --git a/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala b/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala index b53af8599..3702dac67 100644 --- a/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala +++ b/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala @@ -125,7 +125,8 @@ trait SystemSettingsControllerBase extends AccountManagementControllerBase { "maxDiffFiles" -> trim(label("Max diff files", number(required))), "maxDiffLines" -> trim(label("Max diff lines", number(required))) )(RepositoryViewerSettings.apply), - "defaultBranch" -> trim(label("Default branch", text(required))) + "defaultBranch" -> trim(label("Default branch", text(required))), + "showFullName" -> trim(label("Show full name", boolean())) )(SystemSettings.apply).verifying { settings => Vector( if (settings.ssh.enabled && settings.baseUrl.isEmpty) { diff --git a/src/main/scala/gitbucket/core/service/SystemSettingsService.scala b/src/main/scala/gitbucket/core/service/SystemSettingsService.scala index f3c275196..479f68679 100644 --- a/src/main/scala/gitbucket/core/service/SystemSettingsService.scala +++ b/src/main/scala/gitbucket/core/service/SystemSettingsService.scala @@ -93,6 +93,7 @@ trait SystemSettingsService { props.setProperty(RepositoryViewerMaxDiffFiles, settings.repositoryViewer.maxDiffFiles.toString) props.setProperty(RepositoryViewerMaxDiffLines, settings.repositoryViewer.maxDiffLines.toString) props.setProperty(DefaultBranch, settings.defaultBranch) + props.setProperty(ShowFullName, settings.showFullName.toString) Using.resource(new java.io.FileOutputStream(GitBucketConf)) { out => props.store(out, null) @@ -211,7 +212,8 @@ trait SystemSettingsService { getValue(props, RepositoryViewerMaxDiffFiles, 100), getValue(props, RepositoryViewerMaxDiffLines, 1000) ), - getValue(props, DefaultBranch, "main") + getValue(props, DefaultBranch, "main"), + getValue(props, ShowFullName, false) ) } } @@ -238,7 +240,8 @@ object SystemSettingsService { webHook: WebHook, upload: Upload, repositoryViewer: RepositoryViewerSettings, - defaultBranch: String + defaultBranch: String, + showFullName: Boolean ) { def baseUrl(request: HttpServletRequest): String = baseUrl.getOrElse(parseBaseUrl(request)).stripSuffix("/") @@ -457,6 +460,7 @@ object SystemSettingsService { private val RepositoryViewerMaxDiffFiles = "repository_viewer_max_diff_files" private val RepositoryViewerMaxDiffLines = "repository_viewer_max_diff_lines" private val DefaultBranch = "default_branch" + private val ShowFullName = "show_full_name" private def getValue[A: ClassTag](props: java.util.Properties, key: String, default: A): A = { getConfigValue(key).getOrElse { diff --git a/src/main/scala/gitbucket/core/view/AvatarImageProvider.scala b/src/main/scala/gitbucket/core/view/AvatarImageProvider.scala index c38756a0d..43dc67b96 100644 --- a/src/main/scala/gitbucket/core/view/AvatarImageProvider.scala +++ b/src/main/scala/gitbucket/core/view/AvatarImageProvider.scala @@ -47,18 +47,28 @@ trait AvatarImageProvider { self: RequestCache => } } + val displayName = if (!context.settings.showFullName) { + s"@$userName" + } else { + if (mailAddress.isEmpty) { + getAccountByUserNameFromCache(userName).map(_.fullName).getOrElse(s"@$userName") + } else { + getAccountByMailAddressFromCache(mailAddress).map(_.fullName).getOrElse(s"@$userName") + } + } + if (tooltip) { Html( s"""@${StringUtil.escapeHtml(userName)}""".stripMargin + | alt="${StringUtil.escapeHtml(displayName)}" + | data-toggle="tooltip" title="${StringUtil.escapeHtml(displayName)}" />""".stripMargin ) } else { Html( s"""@${StringUtil.escapeHtml(userName)}""".stripMargin + | alt="${StringUtil.escapeHtml(displayName)}" />""".stripMargin ) } } diff --git a/src/main/scala/gitbucket/core/view/helpers.scala b/src/main/scala/gitbucket/core/view/helpers.scala index 3cfb8aaca..88d118948 100644 --- a/src/main/scala/gitbucket/core/view/helpers.scala +++ b/src/main/scala/gitbucket/core/view/helpers.scala @@ -327,12 +327,30 @@ object helpers extends AvatarImageProvider with LinkConverter with RequestCache */ def assets(path: String)(implicit context: Context): String = s"${context.path}/assets${path}?${hashQuery}" + def displayUserName(userName: String, mailAddress: String = "")(implicit context: Context): String = { + val displayName = if (!context.settings.showFullName) { + userName + } else { + if (mailAddress.isEmpty) { + getAccountByUserNameFromCache(userName).map(_.fullName).getOrElse(userName) + } else { + getAccountByMailAddressFromCache(mailAddress).map(_.fullName).getOrElse(userName) + } + } + if (userName == displayName) { + userName + } else { + s"$userName ($displayName)" + } + } + + /** * Generates the text link to the account page. * If user does not exist or disabled, this method returns user name as text without link. */ def user(userName: String, mailAddress: String = "", styleClass: String = "")(implicit context: Context): Html = - userWithContent(userName, mailAddress, styleClass)(Html(StringUtil.escapeHtml(userName))) + userWithContent(userName, mailAddress, styleClass)(Html(StringUtil.escapeHtml(displayUserName(userName, mailAddress)))) /** * Generates the avatar link to the account page. diff --git a/src/main/twirl/gitbucket/core/account/groupform.scala.html b/src/main/twirl/gitbucket/core/account/groupform.scala.html index 6d5ebc2bc..a04b680f7 100644 --- a/src/main/twirl/gitbucket/core/account/groupform.scala.html +++ b/src/main/twirl/gitbucket/core/account/groupform.scala.html @@ -56,16 +56,16 @@ $(function(){ $('#addMember').click(function(){ $('#error-members').text(''); - var userName = $('#memberName').val(); + const userName = $('#memberName').val(); // check empty - if($.trim(userName) == ''){ + if($.trim(userName) === ''){ return false; } // check duplication - var exists = $('#member-list li').filter(function(){ - return $(this).data('name') == userName; + const exists = $('#member-list li').filter(function(){ + return $(this).data('name') === userName; }).length > 0; if(exists){ $('#error-members').text('User has been already added.'); @@ -75,7 +75,7 @@ $(function(){ // check existence $.post('@context.path/_user/existence', { 'userName': userName }, function(data, status){ - if(data == 'user'){ + if(data === 'user'){ addMemberHTML(userName, false); $('#memberName').val(''); } else { @@ -90,7 +90,7 @@ $(function(){ // Don't submit form by ENTER key $('#memberName').keypress(function(e){ - return !(e.keyCode == 13); + return !(e.keyCode === 13); }); $('#delete').click(function(){ @@ -102,11 +102,11 @@ $(function(){ } function addMemberHTML(userName, isManager){ - var memberButton = $(''); + const memberButton = $(''); if(!isManager){ memberButton.addClass('active'); } - var managerButton = $(''); + const managerButton = $(''); if(isManager){ managerButton.addClass('active'); } @@ -123,8 +123,8 @@ $(function(){ } function updateMembers(){ - var members = $('#member-list li').map(function(i, e){ - var userName = $(e).data('name'); + const members = $('#member-list li').map(function(i, e){ + const userName = $(e).data('name'); return userName + ':' + $(e).find('label.active input[type=radio]').attr('value'); }).get().join(','); $('#members').val(members); diff --git a/src/main/twirl/gitbucket/core/admin/settings_system.scala.html b/src/main/twirl/gitbucket/core/admin/settings_system.scala.html index bda508164..4fef350d8 100644 --- a/src/main/twirl/gitbucket/core/admin/settings_system.scala.html +++ b/src/main/twirl/gitbucket/core/admin/settings_system.scala.html @@ -253,6 +253,21 @@ Hide - Hide mail address in user's profile page. + + + + +
+ +
+ +
diff --git a/src/main/twirl/gitbucket/core/admin/userlist.scala.html b/src/main/twirl/gitbucket/core/admin/userlist.scala.html index a6b818a76..554cf8a7a 100644 --- a/src/main/twirl/gitbucket/core/admin/userlist.scala.html +++ b/src/main/twirl/gitbucket/core/admin/userlist.scala.html @@ -25,20 +25,23 @@ Edit } -
- @helpers.avatarLink(account.userName, 20) - @if(account.isRemoved){ - @account.userName - } else { - @account.userName - } - @if(account.isGroupAccount){ - (Group) - } else { - @if(account.isAdmin){ - (Administrator) +
+ + @helpers.avatarLink(account.userName, 20) + @if(account.isRemoved){ + @account.userName } else { - (Normal) + @account.userName + } + + @if(account.isGroupAccount){ + - Group + } else { + (@account.fullName) + @if(account.isAdmin){ + - Administrator + } else { + - Normal } } @if(account.isGroupAccount){ @@ -50,10 +53,10 @@

@if(!account.isGroupAccount){ - @account.mailAddress + @account.mailAddress } @account.url.map { url => - @url + @url }
diff --git a/src/main/twirl/gitbucket/core/issues/issueinfo.scala.html b/src/main/twirl/gitbucket/core/issues/issueinfo.scala.html index bf19bca61..f240eea52 100644 --- a/src/main/twirl/gitbucket/core/issues/issueinfo.scala.html +++ b/src/main/twirl/gitbucket/core/issues/issueinfo.scala.html @@ -131,7 +131,7 @@ @collaborators.map { collaborator =>
  • - @gitbucket.core.helper.html.checkicon(issueAssignees.exists(_.assigneeUserName == collaborator))@helpers.avatar(collaborator, 20) @collaborator + @gitbucket.core.helper.html.checkicon(issueAssignees.exists(_.assigneeUserName == collaborator))@helpers.avatar(collaborator, 20) @helpers.displayUserName(collaborator)
  • } diff --git a/src/main/twirl/gitbucket/core/settings/collaborators.scala.html b/src/main/twirl/gitbucket/core/settings/collaborators.scala.html index b47407b51..f31fdb2a1 100644 --- a/src/main/twirl/gitbucket/core/settings/collaborators.scala.html +++ b/src/main/twirl/gitbucket/core/settings/collaborators.scala.html @@ -48,25 +48,25 @@ $(function(){ }); $('.add').click(function(){ - var id = $(this).attr('id') == 'addCollaborator' ? 'collaborator' : 'group'; + const id = $(this).attr('id') === 'addCollaborator' ? 'collaborator' : 'group'; $('#error-' + id).text(''); - var userName = $('#userName-' + id).val(); + const userName = $('#userName-' + id).val(); // check empty - if($.trim(userName) == ''){ + if($.trim(userName) === ''){ return false; } // check owner - var owner = '@repository.owner' == userName + const owner = '@repository.owner' === userName if(owner){ $('#error-' + id).text('User is owner of this repository.'); return false; } // check duplication - var exists = $('#' + id + '-list li').filter(function(){ - return $(this).data('name') == userName; + const exists = $('#' + id + '-list li').filter(function(){ + return $(this).data('name') === userName; }).length > 0; if(exists){ $('#error-' + id).text('User has been already added.'); @@ -76,7 +76,7 @@ $(function(){ // check existence $.post('@context.path/_user/existence', { 'userName': userName }, function(data, status){ - if(data != ''){ + if(data !== ''){ addListHTML(userName, '@Role.ADMIN.name', '#' + id + '-list'); $('#userName-' + id).val(''); } else { @@ -91,7 +91,7 @@ $(function(){ // Don't submit form by ENTER key $('#userName-collaborator, #userName-group').keypress(function(e){ - return !(e.keyCode == 13); + return !(e.keyCode === 13); }); @collaborators.map { case (collaborator, isGroup) => @@ -99,16 +99,16 @@ $(function(){ } function addListHTML(userName, role, id){ - var adminButton = $(''); - if(role == '@Role.ADMIN.name'){ + const adminButton = $(''); + if(role === '@Role.ADMIN.name'){ adminButton.addClass('active'); } - var writeButton = $(''); - if(role == '@Role.DEVELOPER.name'){ + const writeButton = $(''); + if(role === '@Role.DEVELOPER.name'){ writeButton.addClass('active'); } - var readButton = $(''); - if(role == '@Role.GUEST.name'){ + const readButton = $(''); + if(role === '@Role.GUEST.name'){ readButton.addClass('active'); } @@ -124,13 +124,13 @@ $(function(){ } function updateValues(){ - var collaborators = $('#collaborator-list li').map(function(i, e){ - var userName = $(e).data('name'); + const collaborators = $('#collaborator-list li').map(function(i, e){ + const userName = $(e).data('name'); return userName + ':' + $(e).find('label.active input[type=radio]').attr('value'); }).get().join(','); - var groups = $('#group-list li').map(function(i, e){ - var userName = $(e).data('name'); + const groups = $('#group-list li').map(function(i, e){ + const userName = $(e).data('name'); return userName + ':' + $(e).find('label.active input[type=radio]').attr('value'); }).get().join(','); diff --git a/src/test/scala/gitbucket/core/service/ServiceSpecBase.scala b/src/test/scala/gitbucket/core/service/ServiceSpecBase.scala index 340da6803..25431ca8b 100644 --- a/src/test/scala/gitbucket/core/service/ServiceSpecBase.scala +++ b/src/test/scala/gitbucket/core/service/ServiceSpecBase.scala @@ -85,7 +85,8 @@ trait ServiceSpecBase { maxDiffFiles = 100, maxDiffLines = 1000 ), - defaultBranch = "main" + defaultBranch = "main", + showFullName = false ) def withTestDB[A](action: (Session) => A): A = { diff --git a/src/test/scala/gitbucket/core/view/AvatarImageProviderSpec.scala b/src/test/scala/gitbucket/core/view/AvatarImageProviderSpec.scala index 543dc3519..29ec86c1b 100644 --- a/src/test/scala/gitbucket/core/view/AvatarImageProviderSpec.scala +++ b/src/test/scala/gitbucket/core/view/AvatarImageProviderSpec.scala @@ -107,7 +107,7 @@ class AvatarImageProviderSpec extends AnyFunSpec { provider.toHtml("user", 20, "hoge@hoge.com", true).toString == """@user""".stripMargin + | data-toggle="tooltip" title="@user" />""".stripMargin ) } @@ -125,7 +125,7 @@ class AvatarImageProviderSpec extends AnyFunSpec { provider.toHtml(""""""", 20, "hoge@hoge.com", true).toString == """@<user>"<name>""".stripMargin + | data-toggle="tooltip" title="@<user>"<name>" />""".stripMargin ) } } @@ -196,7 +196,8 @@ class AvatarImageProviderSpec extends AnyFunSpec { maxDiffFiles = 100, maxDiffLines = 1000 ), - "main" + defaultBranch = "main", + showFullName = false ) /**