diff --git a/api4/team_test.go b/api4/team_test.go
index 665db95f58..b517f67feb 100644
--- a/api4/team_test.go
+++ b/api4/team_test.go
@@ -1422,7 +1422,8 @@ func TestInviteUsersToTeam(t *testing.T) {
t.Fatal("should return true")
}
- expectedSubject := "[Mattermost] " + th.SystemAdminUser.GetDisplayName() + " invited you to join " + th.BasicTeam.DisplayName + " Team"
+ nameFormat := *utils.Cfg.TeamSettings.TeammateNameDisplay
+ expectedSubject := "[Mattermost] " + th.SystemAdminUser.GetDisplayName(nameFormat) + " invited you to join " + th.BasicTeam.DisplayName + " Team"
//Check if the email was send to the rigth email address
for _, email := range emailList {
var resultsMailbox utils.JSONMessageHeaderInbucket
diff --git a/app/diagnostics.go b/app/diagnostics.go
index 65d67742ea..dc0dbe597d 100644
--- a/app/diagnostics.go
+++ b/app/diagnostics.go
@@ -209,6 +209,7 @@ func trackConfig() {
"max_notifications_per_channel": *utils.Cfg.TeamSettings.MaxNotificationsPerChannel,
"max_users_per_team": utils.Cfg.TeamSettings.MaxUsersPerTeam,
"max_channels_per_team": *utils.Cfg.TeamSettings.MaxChannelsPerTeam,
+ "teammate_name_display": *utils.Cfg.TeamSettings.TeammateNameDisplay,
"isdefault_site_name": isDefault(utils.Cfg.TeamSettings.SiteName, "Mattermost"),
"isdefault_custom_brand_text": isDefault(*utils.Cfg.TeamSettings.CustomBrandText, model.TEAM_SETTINGS_DEFAULT_CUSTOM_BRAND_TEXT),
"isdefault_custom_description_text": isDefault(*utils.Cfg.TeamSettings.CustomDescriptionText, model.TEAM_SETTINGS_DEFAULT_CUSTOM_DESCRIPTION_TEXT),
diff --git a/app/email_batching.go b/app/email_batching.go
index 6d7a376eff..5e4a36daff 100644
--- a/app/email_batching.go
+++ b/app/email_batching.go
@@ -4,7 +4,6 @@
package app
import (
- "database/sql"
"fmt"
"html/template"
"strconv"
@@ -163,7 +162,6 @@ func (job *EmailBatchingJob) checkPendingNotifications(now time.Time, handler fu
func sendBatchedEmailNotification(userId string, notifications []*batchedNotification) {
uchan := Srv.Store.User().Get(userId)
- pchan := Srv.Store.Preference().Get(userId, model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_DISPLAY_NAME_FORMAT)
var user *model.User
if result := <-uchan; result.Err != nil {
@@ -174,17 +172,7 @@ func sendBatchedEmailNotification(userId string, notifications []*batchedNotific
}
translateFunc := utils.GetUserTranslations(user.Locale)
-
- var displayNameFormat string
- if result := <-pchan; result.Err != nil && result.Err.DetailedError != sql.ErrNoRows.Error() {
- l4g.Warn("api.email_batching.send_batched_email_notification.preferences.app_error")
- return
- } else if result.Err != nil {
- // no display name format saved, so fall back to default
- displayNameFormat = model.PREFERENCE_DEFAULT_DISPLAY_NAME_FORMAT
- } else {
- displayNameFormat = result.Data.(model.Preference).Value
- }
+ displayNameFormat := *utils.Cfg.TeamSettings.TeammateNameDisplay
var contents string
for _, notification := range notifications {
@@ -236,7 +224,7 @@ func renderBatchedPost(template *utils.HTMLTemplate, post *model.Post, teamName
l4g.Warn(utils.T("api.email_batching.render_batched_post.sender.app_error"))
return ""
} else {
- template.Props["SenderName"] = result.Data.(*model.User).GetDisplayNameForPreference(displayNameFormat)
+ template.Props["SenderName"] = result.Data.(*model.User).GetDisplayName(displayNameFormat)
}
if result := <-cchan; result.Err != nil {
diff --git a/app/import_test.go b/app/import_test.go
index 365383bad7..0a45cca039 100644
--- a/app/import_test.go
+++ b/app/import_test.go
@@ -1586,7 +1586,6 @@ func TestImportImportUser(t *testing.T) {
Theme: ptrStr(`{"awayIndicator":"#DCBD4E","buttonBg":"#23A2FF","buttonColor":"#FFFFFF","centerChannelBg":"#ffffff","centerChannelColor":"#333333","codeTheme":"github","image":"/static/files/a4a388b38b32678e83823ef1b3e17766.png","linkColor":"#2389d7","mentionBj":"#2389d7","mentionColor":"#ffffff","mentionHighlightBg":"#fff2bb","mentionHighlightLink":"#2f81b7","newMessageSeparator":"#FF8800","onlineIndicator":"#7DBE00","sidebarBg":"#fafafa","sidebarHeaderBg":"#3481B9","sidebarHeaderTextColor":"#ffffff","sidebarText":"#333333","sidebarTextActiveBorder":"#378FD2","sidebarTextActiveColor":"#111111","sidebarTextHoverBg":"#e6f2fa","sidebarUnreadText":"#333333","type":"Mattermost"}`),
SelectedFont: ptrStr("Roboto Slab"),
UseMilitaryTime: ptrStr("true"),
- NameFormat: ptrStr("nickname_full_name"),
CollapsePreviews: ptrStr("true"),
MessageDisplay: ptrStr("compact"),
ChannelDisplayMode: ptrStr("centered"),
@@ -1625,10 +1624,6 @@ func TestImportImportUser(t *testing.T) {
t.Fatalf("Preference does not match.")
}
- if preference.Name == "name_format" && preference.Value != *data.NameFormat {
- t.Fatalf("Preference does not match.")
- }
-
if preference.Name == "collapse_previews" && preference.Value != *data.CollapsePreviews {
t.Fatalf("Preference does not match.")
}
@@ -1650,7 +1645,6 @@ func TestImportImportUser(t *testing.T) {
Theme: ptrStr(`{"awayIndicator":"#123456","buttonBg":"#23A2FF","buttonColor":"#FFFFFF","centerChannelBg":"#ffffff","centerChannelColor":"#333333","codeTheme":"github","image":"/static/files/a4a388b38b32678e83823ef1b3e17766.png","linkColor":"#2389d7","mentionBj":"#2389d7","mentionColor":"#ffffff","mentionHighlightBg":"#fff2bb","mentionHighlightLink":"#2f81b7","newMessageSeparator":"#FF8800","onlineIndicator":"#7DBE00","sidebarBg":"#fafafa","sidebarHeaderBg":"#3481B9","sidebarHeaderTextColor":"#ffffff","sidebarText":"#333333","sidebarTextActiveBorder":"#378FD2","sidebarTextActiveColor":"#111111","sidebarTextHoverBg":"#e6f2fa","sidebarUnreadText":"#333333","type":"Mattermost"}`),
SelectedFont: ptrStr("Lato"),
UseMilitaryTime: ptrStr("false"),
- NameFormat: ptrStr("full_name"),
CollapsePreviews: ptrStr("false"),
MessageDisplay: ptrStr("clean"),
ChannelDisplayMode: ptrStr("full"),
@@ -1684,10 +1678,6 @@ func TestImportImportUser(t *testing.T) {
t.Fatalf("Preference does not match.")
}
- if preference.Name == "name_format" && preference.Value != *data.NameFormat {
- t.Fatalf("Preference does not match.")
- }
-
if preference.Name == "collapse_previews" && preference.Value != *data.CollapsePreviews {
t.Fatalf("Preference does not match.")
}
diff --git a/app/team.go b/app/team.go
index be15b8a39b..8f2f7cfcb9 100644
--- a/app/team.go
+++ b/app/team.go
@@ -657,7 +657,8 @@ func InviteNewUsersToTeam(emailList []string, teamId, senderId string) *model.Ap
user = result.Data.(*model.User)
}
- SendInviteEmails(team, user.GetDisplayName(), emailList, utils.GetSiteURL())
+ nameFormat := *utils.Cfg.TeamSettings.TeammateNameDisplay
+ SendInviteEmails(team, user.GetDisplayName(nameFormat), emailList, utils.GetSiteURL())
return nil
}
diff --git a/i18n/en.json b/i18n/en.json
index 923fd4b667..5ddaa9723f 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -4311,6 +4311,10 @@
"id": "model.config.is_valid.sql_query_timeout.app_error",
"translation": "Invalid query timeout for SQL settings. Must be a positive number."
},
+ {
+ "id": "model.config.is_valid.teammate_name_display.app_error",
+ "translation": "Invalid teammate display. Must be 'full_name', 'nickname_full_name' or 'username'"
+ },
{
"id": "model.config.is_valid.time_between_user_typing.app_error",
"translation": "Time between user typing updates should not be set to less than 1000 milliseconds."
diff --git a/model/config.go b/model/config.go
index 6d62aab913..5662ee9c07 100644
--- a/model/config.go
+++ b/model/config.go
@@ -39,6 +39,10 @@ const (
DIRECT_MESSAGE_ANY = "any"
DIRECT_MESSAGE_TEAM = "team"
+ SHOW_USERNAME = "username"
+ SHOW_NICKNAME_FULLNAME = "nickname_full_name"
+ SHOW_FULLNAME = "full_name"
+
PERMISSIONS_ALL = "all"
PERMISSIONS_CHANNEL_ADMIN = "channel_admin"
PERMISSIONS_TEAM_ADMIN = "team_admin"
@@ -322,6 +326,7 @@ type TeamSettings struct {
UserStatusAwayTimeout *int64
MaxChannelsPerTeam *int64
MaxNotificationsPerChannel *int64
+ TeammateNameDisplay *string
}
type LdapSettings struct {
@@ -702,6 +707,11 @@ func (o *Config) SetDefaults() {
*o.TeamSettings.MaxNotificationsPerChannel = 1000
}
+ if o.TeamSettings.TeammateNameDisplay == nil {
+ o.TeamSettings.TeammateNameDisplay = new(string)
+ *o.TeamSettings.TeammateNameDisplay = SHOW_FULLNAME
+ }
+
if o.EmailSettings.EnableSignInWithEmail == nil {
o.EmailSettings.EnableSignInWithEmail = new(bool)
@@ -1394,6 +1404,10 @@ func (o *Config) IsValid() *AppError {
return NewLocAppError("Config.IsValid", "model.config.is_valid.restrict_direct_message.app_error", nil, "")
}
+ if !(*o.TeamSettings.TeammateNameDisplay == SHOW_FULLNAME || *o.TeamSettings.TeammateNameDisplay == SHOW_NICKNAME_FULLNAME || *o.TeamSettings.TeammateNameDisplay == SHOW_USERNAME) {
+ return NewLocAppError("Config.IsValid", "model.config.is_valid.teammate_name_display.app_error", nil, "")
+ }
+
if len(o.SqlSettings.AtRestEncryptKey) < 32 {
return NewLocAppError("Config.IsValid", "model.config.is_valid.encrypt_sql.app_error", nil, "")
}
diff --git a/model/preference.go b/model/preference.go
index 4d534b17b7..589f8b5a9a 100644
--- a/model/preference.go
+++ b/model/preference.go
@@ -17,13 +17,8 @@ const (
PREFERENCE_CATEGORY_ADVANCED_SETTINGS = "advanced_settings"
PREFERENCE_CATEGORY_FLAGGED_POST = "flagged_post"
- PREFERENCE_CATEGORY_DISPLAY_SETTINGS = "display_settings"
- PREFERENCE_NAME_COLLAPSE_SETTING = "collapse_previews"
- PREFERENCE_NAME_DISPLAY_NAME_FORMAT = "name_format"
- PREFERENCE_VALUE_DISPLAY_NAME_NICKNAME = "nickname_full_name"
- PREFERENCE_VALUE_DISPLAY_NAME_FULL = "full_name"
- PREFERENCE_VALUE_DISPLAY_NAME_USERNAME = "username"
- PREFERENCE_DEFAULT_DISPLAY_NAME_FORMAT = PREFERENCE_VALUE_DISPLAY_NAME_USERNAME
+ PREFERENCE_CATEGORY_DISPLAY_SETTINGS = "display_settings"
+ PREFERENCE_NAME_COLLAPSE_SETTING = "collapse_previews"
PREFERENCE_CATEGORY_THEME = "theme"
// the name for theme props is the team id
diff --git a/model/user.go b/model/user.go
index 970e777fc8..8e5c8fcc13 100644
--- a/model/user.go
+++ b/model/user.go
@@ -383,26 +383,16 @@ func (u *User) GetFullName() string {
}
}
-func (u *User) GetDisplayName() string {
- if u.Nickname != "" {
- return u.Nickname
- } else if fullName := u.GetFullName(); fullName != "" {
- return fullName
- } else {
- return u.Username
- }
-}
-
-func (u *User) GetDisplayNameForPreference(nameFormat string) string {
+func (u *User) GetDisplayName(nameFormat string) string {
displayName := u.Username
- if nameFormat == PREFERENCE_VALUE_DISPLAY_NAME_NICKNAME {
+ if nameFormat == SHOW_NICKNAME_FULLNAME {
if u.Nickname != "" {
displayName = u.Nickname
} else if fullName := u.GetFullName(); fullName != "" {
displayName = fullName
}
- } else if nameFormat == PREFERENCE_VALUE_DISPLAY_NAME_FULL {
+ } else if nameFormat == SHOW_FULLNAME {
if fullName := u.GetFullName(); fullName != "" {
displayName = fullName
}
diff --git a/model/user_test.go b/model/user_test.go
index fc153248f8..4502263c39 100644
--- a/model/user_test.go
+++ b/model/user_test.go
@@ -179,20 +179,37 @@ func TestUserGetFullName(t *testing.T) {
}
func TestUserGetDisplayName(t *testing.T) {
- user := User{Username: "user"}
+ user := User{Username: "username"}
- if displayName := user.GetDisplayName(); displayName != "user" {
+ if displayName := user.GetDisplayName(SHOW_FULLNAME); displayName != "username" {
+ t.Fatal("Display name should be username")
+ }
+
+ if displayName := user.GetDisplayName(SHOW_NICKNAME_FULLNAME); displayName != "username" {
+ t.Fatal("Display name should be username")
+ }
+
+ if displayName := user.GetDisplayName(SHOW_USERNAME); displayName != "username" {
t.Fatal("Display name should be username")
}
user.FirstName = "first"
user.LastName = "last"
- if displayName := user.GetDisplayName(); displayName != "first last" {
+
+ if displayName := user.GetDisplayName(SHOW_FULLNAME); displayName != "first last" {
t.Fatal("Display name should be full name")
}
+ if displayName := user.GetDisplayName(SHOW_NICKNAME_FULLNAME); displayName != "first last" {
+ t.Fatal("Display name should be full name since there is no nickname")
+ }
+
+ if displayName := user.GetDisplayName(SHOW_USERNAME); displayName != "username" {
+ t.Fatal("Display name should be username")
+ }
+
user.Nickname = "nickname"
- if displayName := user.GetDisplayName(); displayName != "nickname" {
+ if displayName := user.GetDisplayName(SHOW_NICKNAME_FULLNAME); displayName != "nickname" {
t.Fatal("Display name should be nickname")
}
}
diff --git a/utils/config.go b/utils/config.go
index 4136a65152..66673fa4f3 100644
--- a/utils/config.go
+++ b/utils/config.go
@@ -411,6 +411,7 @@ func getClientConfig(c *model.Config) map[string]string {
props["RestrictPublicChannelDeletion"] = *c.TeamSettings.RestrictPublicChannelDeletion
props["RestrictPrivateChannelDeletion"] = *c.TeamSettings.RestrictPrivateChannelDeletion
props["RestrictPrivateChannelManageMembers"] = *c.TeamSettings.RestrictPrivateChannelManageMembers
+ props["TeammateNameDisplay"] = *c.TeamSettings.TeammateNameDisplay
props["EnableOAuthServiceProvider"] = strconv.FormatBool(c.ServiceSettings.EnableOAuthServiceProvider)
props["GoogleDeveloperKey"] = c.ServiceSettings.GoogleDeveloperKey
diff --git a/webapp/components/admin_console/users_and_teams_settings.jsx b/webapp/components/admin_console/users_and_teams_settings.jsx
index 4535aec7b0..9d33f06484 100644
--- a/webapp/components/admin_console/users_and_teams_settings.jsx
+++ b/webapp/components/admin_console/users_and_teams_settings.jsx
@@ -31,6 +31,7 @@ export default class UsersAndTeamsSettings extends AdminSettings {
config.TeamSettings.MaxUsersPerTeam = this.parseIntNonZero(this.state.maxUsersPerTeam, Constants.DEFAULT_MAX_USERS_PER_TEAM);
config.TeamSettings.RestrictCreationToDomains = this.state.restrictCreationToDomains;
config.TeamSettings.RestrictDirectMessage = this.state.restrictDirectMessage;
+ config.TeamSettings.TeammateNameDisplay = this.state.teammateNameDisplay;
config.TeamSettings.MaxChannelsPerTeam = this.parseIntNonZero(this.state.maxChannelsPerTeam, Constants.DEFAULT_MAX_CHANNELS_PER_TEAM);
config.TeamSettings.MaxNotificationsPerChannel = this.parseIntNonZero(this.state.maxNotificationsPerChannel, Constants.DEFAULT_MAX_NOTIFICATIONS_PER_CHANNEL);
@@ -44,6 +45,7 @@ export default class UsersAndTeamsSettings extends AdminSettings {
maxUsersPerTeam: config.TeamSettings.MaxUsersPerTeam,
restrictCreationToDomains: config.TeamSettings.RestrictCreationToDomains,
restrictDirectMessage: config.TeamSettings.RestrictDirectMessage,
+ teammateNameDisplay: config.TeamSettings.TeammateNameDisplay,
maxChannelsPerTeam: config.TeamSettings.MaxChannelsPerTeam,
maxNotificationsPerChannel: config.TeamSettings.MaxNotificationsPerChannel
};
@@ -188,6 +190,28 @@ export default class UsersAndTeamsSettings extends AdminSettings {
value={this.state.restrictDirectMessage}
onChange={this.handleChange}
/>
+