From 1605fa5102e7d5d76a02456130097d3ab82c2a2b Mon Sep 17 00:00:00 2001 From: David Meza Date: Tue, 5 Sep 2017 19:28:46 -0500 Subject: [PATCH] Configs for themes in `Display Settings`: hide themes options, hide custom themes, specific list of themes (#7173) * Add configuration to enable or disable choosing themes in Display Settings. Only for Licensed servers. * Add configuration to enable or disable choosing custom themes in Display Settings. Only for Licensed servers. * Add configuration to enable or disable a specific list of themes to choose in Display Settings. Only for Licensed servers. * Added config value and logic for "DefaultTheme" * Fix problem with undefined values when the server is not licensed --- app/diagnostics.go | 8 + config/default.json | 6 + model/config.go | 29 ++++ model/license.go | 6 + utils/config.go | 8 +- .../user_settings/premade_theme_chooser.jsx | 7 + .../user_settings/user_settings_display.jsx | 19 ++- .../user_settings/user_settings_theme.jsx | 157 +++++++++--------- webapp/stores/preference_store.jsx | 6 + 9 files changed, 163 insertions(+), 83 deletions(-) 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 = ( + + ); + } + return (
@@ -632,12 +644,7 @@ export default class UserSettingsDisplay extends React.Component { />
- + {themeSection}
{clockSection}
diff --git a/webapp/components/user_settings/user_settings_theme.jsx b/webapp/components/user_settings/user_settings_theme.jsx index 4f39cffa91..871e3ccaeb 100644 --- a/webapp/components/user_settings/user_settings_theme.jsx +++ b/webapp/components/user_settings/user_settings_theme.jsx @@ -180,10 +180,11 @@ export default class ThemeSetting extends React.Component { } const displayCustom = this.state.type === 'custom'; + const allowCustomThemes = global.mm_config.AllowCustomThemes !== 'false'; let custom; let premade; - if (displayCustom) { + if (displayCustom && allowCustomThemes) { custom = (
- -
-
- ); + if (allowCustomThemes) { + inputs.push( +
+ +
+
+ ); + } inputs.push(premade); - inputs.push( -
- -
- ); - - inputs.push(custom); - - inputs.push( -
-
- - - -
- ); + +
+ ); - inputs.push( - + ); + + inputs.push( +
- - -
- ); + + + +
+ ); + } let allTeamsCheckbox = null; if (this.state.showAllTeamsCheckbox) { diff --git a/webapp/stores/preference_store.jsx b/webapp/stores/preference_store.jsx index f3476d9eab..cd8ae68be6 100644 --- a/webapp/stores/preference_store.jsx +++ b/webapp/stores/preference_store.jsx @@ -141,6 +141,12 @@ class PreferenceStore extends EventEmitter { return this.getObject(Constants.Preferences.CATEGORY_THEME, ''); } + for (const k in Constants.THEMES) { + if (Constants.THEMES.hasOwnProperty(k) && k === global.mm_config.DefaultTheme) { + return Constants.THEMES[k]; + } + } + return Constants.THEMES.default; }