diff --git a/app/diagnostics.go b/app/diagnostics.go
index 713d8aa264..98043d0a0b 100644
--- a/app/diagnostics.go
+++ b/app/diagnostics.go
@@ -26,6 +26,7 @@ const (
TRACK_CONFIG_RATE = "config_rate"
TRACK_CONFIG_EMAIL = "config_email"
TRACK_CONFIG_PRIVACY = "config_privacy"
+ TRACK_CONFIG_THEME = "config_theme"
TRACK_CONFIG_OAUTH = "config_oauth"
TRACK_CONFIG_LDAP = "config_ldap"
TRACK_CONFIG_COMPLIANCE = "config_compliance"
@@ -331,6 +332,13 @@ func trackConfig() {
"show_full_name": utils.Cfg.PrivacySettings.ShowFullName,
})
+ SendDiagnostic(TRACK_CONFIG_THEME, map[string]interface{}{
+ "enable_theme_selection": *utils.Cfg.ThemeSettings.EnableThemeSelection,
+ "isdefault_default_theme": isDefault(*utils.Cfg.ThemeSettings.DefaultTheme, model.TEAM_SETTINGS_DEFAULT_TEAM_TEXT),
+ "allow_custom_themes": *utils.Cfg.ThemeSettings.AllowCustomThemes,
+ "allowed_themes": len(utils.Cfg.ThemeSettings.AllowedThemes),
+ })
+
SendDiagnostic(TRACK_CONFIG_OAUTH, map[string]interface{}{
"enable_gitlab": utils.Cfg.GitLabSettings.Enable,
"enable_google": utils.Cfg.GoogleSettings.Enable,
diff --git a/config/default.json b/config/default.json
index 50bf7b32b0..b74cc712a3 100644
--- a/config/default.json
+++ b/config/default.json
@@ -186,6 +186,12 @@
"BannerTextColor": "#333333",
"AllowBannerDismissal": true
},
+ "ThemeSettings": {
+ "EnableThemeSelection": true,
+ "DefaultTheme": "default",
+ "AllowCustomThemes": true,
+ "AllowedThemes": []
+ },
"GitLabSettings": {
"Enable": false,
"Secret": "",
diff --git a/model/config.go b/model/config.go
index c6fd84ed0f..38e09d216e 100644
--- a/model/config.go
+++ b/model/config.go
@@ -132,6 +132,8 @@ const (
ANNOUNCEMENT_SETTINGS_DEFAULT_BANNER_COLOR = "#f2a93b"
ANNOUNCEMENT_SETTINGS_DEFAULT_BANNER_TEXT_COLOR = "#333333"
+ TEAM_SETTINGS_DEFAULT_TEAM_TEXT = "default"
+
ELASTICSEARCH_SETTINGS_DEFAULT_CONNECTION_URL = ""
ELASTICSEARCH_SETTINGS_DEFAULT_USERNAME = ""
ELASTICSEARCH_SETTINGS_DEFAULT_PASSWORD = ""
@@ -335,6 +337,13 @@ type AnnouncementSettings struct {
AllowBannerDismissal *bool
}
+type ThemeSettings struct {
+ EnableThemeSelection *bool
+ DefaultTheme *string
+ AllowCustomThemes *bool
+ AllowedThemes []string
+}
+
type TeamSettings struct {
SiteName string
MaxUsersPerTeam *int
@@ -500,6 +509,7 @@ type Config struct {
PrivacySettings PrivacySettings
SupportSettings SupportSettings
AnnouncementSettings AnnouncementSettings
+ ThemeSettings ThemeSettings
GitLabSettings SSOSettings
GoogleSettings SSOSettings
Office365Settings SSOSettings
@@ -1003,6 +1013,25 @@ func (o *Config) SetDefaults() {
*o.AnnouncementSettings.AllowBannerDismissal = true
}
+ if o.ThemeSettings.EnableThemeSelection == nil {
+ o.ThemeSettings.EnableThemeSelection = new(bool)
+ *o.ThemeSettings.EnableThemeSelection = true
+ }
+
+ if o.ThemeSettings.DefaultTheme == nil {
+ o.ThemeSettings.DefaultTheme = new(string)
+ *o.ThemeSettings.DefaultTheme = TEAM_SETTINGS_DEFAULT_TEAM_TEXT
+ }
+
+ if o.ThemeSettings.AllowCustomThemes == nil {
+ o.ThemeSettings.AllowCustomThemes = new(bool)
+ *o.ThemeSettings.AllowCustomThemes = true
+ }
+
+ if o.ThemeSettings.AllowedThemes == nil {
+ o.ThemeSettings.AllowedThemes = []string{}
+ }
+
if o.LdapSettings.Enable == nil {
o.LdapSettings.Enable = new(bool)
*o.LdapSettings.Enable = false
diff --git a/model/license.go b/model/license.go
index ea10897230..d6fbcb9376 100644
--- a/model/license.go
+++ b/model/license.go
@@ -51,6 +51,7 @@ type Features struct {
PasswordRequirements *bool `json:"password_requirements"`
Elasticsearch *bool `json:"elastic_search"`
Announcement *bool `json:"announcement"`
+ ThemeManagement *bool `json:"theme_management"`
EmailNotificationContents *bool `json:"email_notification_contents"`
// after we enabled more features for webrtc we'll need to control them with this
@@ -152,6 +153,11 @@ func (f *Features) SetDefaults() {
*f.Announcement = true
}
+ if f.ThemeManagement == nil {
+ f.ThemeManagement = new(bool)
+ *f.ThemeManagement = true
+ }
+
if f.EmailNotificationContents == nil {
f.EmailNotificationContents = new(bool)
*f.EmailNotificationContents = *f.FutureFeatures
diff --git a/utils/config.go b/utils/config.go
index c77d655dce..0a1e0149e9 100644
--- a/utils/config.go
+++ b/utils/config.go
@@ -539,7 +539,6 @@ func getClientConfig(c *model.Config) map[string]string {
props["PluginsEnabled"] = strconv.FormatBool(*c.PluginSettings.Enable)
if IsLicensed() {
-
License := License()
props["ExperimentalTownSquareIsReadOnly"] = strconv.FormatBool(*c.TeamSettings.ExperimentalTownSquareIsReadOnly)
@@ -605,6 +604,13 @@ func getClientConfig(c *model.Config) map[string]string {
props["BannerTextColor"] = *c.AnnouncementSettings.BannerTextColor
props["AllowBannerDismissal"] = strconv.FormatBool(*c.AnnouncementSettings.AllowBannerDismissal)
}
+
+ if *License.Features.ThemeManagement {
+ props["EnableThemeSelection"] = strconv.FormatBool(*c.ThemeSettings.EnableThemeSelection)
+ props["DefaultTheme"] = *c.ThemeSettings.DefaultTheme
+ props["AllowCustomThemes"] = strconv.FormatBool(*c.ThemeSettings.AllowCustomThemes)
+ props["AllowedThemes"] = strings.Join(c.ThemeSettings.AllowedThemes, ",")
+ }
}
return props
diff --git a/webapp/components/user_settings/premade_theme_chooser.jsx b/webapp/components/user_settings/premade_theme_chooser.jsx
index 6536285959..1bb2c6be95 100644
--- a/webapp/components/user_settings/premade_theme_chooser.jsx
+++ b/webapp/components/user_settings/premade_theme_chooser.jsx
@@ -18,8 +18,15 @@ export default class PremadeThemeChooser extends React.Component {
const theme = this.props.theme;
const premadeThemes = [];
+ const allowedThemes = global.mm_config.AllowedThemes ? global.mm_config.AllowedThemes.split(',') : [];
+ const hasAllowedThemes = allowedThemes.length > 1 || (allowedThemes[0] && allowedThemes[0].trim().length > 0);
+
for (const k in Constants.THEMES) {
if (Constants.THEMES.hasOwnProperty(k)) {
+ if (hasAllowedThemes && allowedThemes.indexOf(k) < 0) {
+ continue;
+ }
+
const premadeTheme = $.extend(true, {}, Constants.THEMES[k]);
let activeClass = '';
diff --git a/webapp/components/user_settings/user_settings_display.jsx b/webapp/components/user_settings/user_settings_display.jsx
index 74a939994f..f10b299001 100644
--- a/webapp/components/user_settings/user_settings_display.jsx
+++ b/webapp/components/user_settings/user_settings_display.jsx
@@ -595,6 +595,18 @@ export default class UserSettingsDisplay extends React.Component {
);
}
+ let themeSection;
+ if (global.mm_config.EnableThemeSelection !== 'false') {
+ themeSection = (
+