FEATURE: allow disabling theme components (#7812)

FEATURE: allow disabling theme components (#7812)

This allows you to temporarily disable components without having to remove them from a theme.

This feature is very handy when doing quick fix engineering.

diff --git a/app/assets/javascripts/admin/components/themes-list-item.js.es6 b/app/assets/javascripts/admin/components/themes-list-item.js.es6
index 5043f6f..a3a84ea 100644
--- a/app/assets/javascripts/admin/components/themes-list-item.js.es6
+++ b/app/assets/javascripts/admin/components/themes-list-item.js.es6
@@ -2,6 +2,8 @@ import {
   default as computed,
   observes
 } from "ember-addons/ember-computed-decorators";
+import { iconHTML } from "discourse-common/lib/icon-library";
+import { escape } from "pretty-text/sanitizer";
 
 const MAX_COMPONENTS = 4;
 
@@ -64,7 +66,10 @@ export default Ember.Component.extend({
     children = this.childrenExpanded
       ? children
       : children.slice(0, MAX_COMPONENTS);
-    return children.map(t => t.get("name"));
+    return children.map(t => {
+      const name = escape(t.name);
+      return t.enabled ? name : `${iconHTML("ban")} ${name}`;
+    });
   },
 
   @computed("children")
diff --git a/app/assets/javascripts/admin/controllers/admin-customize-themes-show.js.es6 b/app/assets/javascripts/admin/controllers/admin-customize-themes-show.js.es6
index 552a1d3..fc211ce 100644
--- a/app/assets/javascripts/admin/controllers/admin-customize-themes-show.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-customize-themes-show.js.es6
@@ -301,6 +301,20 @@ export default Ember.Controller.extend({
       } else {
         this.commitSwitchType();
       }
+    },
+
+    enableComponent() {
+      this.model.set("enabled", true);
+      this.model
+        .saveChanges("enabled")
+        .catch(() => this.model.set("enabled", false));
+    },
+
+    disableComponent() {
+      this.model.set("enabled", false);
+      this.model
+        .saveChanges("enabled")
+        .catch(() => this.model.set("enabled", true));
     }
   }
 });
diff --git a/app/assets/javascripts/admin/templates/components/themes-list-item.hbs b/app/assets/javascripts/admin/templates/components/themes-list-item.hbs
index 6634886..aba96d1 100644
--- a/app/assets/javascripts/admin/templates/components/themes-list-item.hbs
+++ b/app/assets/javascripts/admin/templates/components/themes-list-item.hbs
@@ -17,6 +17,9 @@
         {{#if theme.isBroken}}
           {{d-icon "exclamation-circle" class="broken-indicator" title="admin.customize.theme.broken_theme_tooltip"}}
         {{/if}}
+        {{#unless theme.enabled}}
+          {{d-icon "ban" class="light-grey-icon" title="admin.customize.theme.disabled_component_tooltip"}}
+        {{/unless}}
       {{else}}
         {{d-icon "caret-right"}}
       {{/unless}}
@@ -25,7 +28,7 @@
 
   {{#if displayComponents}}
     <div class="components-list">
-      <span class="components">{{childrenString}}</span>
+      <span class="components">{{{childrenString}}}</span>
 
       {{#if displayHasMore}}
         <span {{action "toggleChildrenExpanded"}} class="others-count">
diff --git a/app/assets/javascripts/admin/templates/customize-themes-show.hbs b/app/assets/javascripts/admin/templates/customize-themes-show.hbs
index e4796c8..f7e198d 100644
--- a/app/assets/javascripts/admin/templates/customize-themes-show.hbs
+++ b/app/assets/javascripts/admin/templates/customize-themes-show.hbs
@@ -16,7 +16,7 @@
     </div>
   {{/each}}
 
-  {{#unless model.enabled}}
+  {{#unless model.supported}}
     <div class="alert alert-error">
       {{i18n "admin.customize.theme.required_version.error"}}
       {{#if model.remote_theme.minimum_discourse_version}}
@@ -28,6 +28,26 @@
     </div>
   {{/unless}}
 
+  {{#unless model.enabled}}
+    <div class="alert alert-error">
+      {{#if model.disabled_by}}
+        {{i18n "admin.customize.theme.disabled_by"}}
+        {{#user-link user=model.disabled_by}}
+          {{avatar model.disabled_by imageSize="tiny"}}
+          {{model.disabled_by.username}}
+        {{/user-link}}
+        {{format-date model.disabled_at leaveAgo="true"}}
+      {{else}}
+        {{i18n "admin.customize.theme.disabled"}}
+      {{/if}}
+      {{d-button
+        class='btn-default'
+        action=(action "enableComponent")
+        icon="check"
+        label="admin.customize.theme.enable"}}
+    </div>
+  {{/unless}}
+
   {{#unless model.component}}
     <div class="control-unit">
       {{inline-edit-checkbox action=(action "applyDefault") labelKey="admin.customize.theme.is_default" checked=model.default}}
@@ -204,7 +224,13 @@
       {{#if model.childThemes.length}}
         <ul class='removable-list'>
           {{#each model.childThemes as |child|}}
-            <li>{{#link-to 'adminCustomizeThemes.show' child replace=true class='col'}}{{child.name}}{{/link-to}} {{d-button action=(action "removeChildTheme") actionParam=child class="btn-default cancel-edit col" icon="times"}}</li>
+            <li class={{unless child.enabled "disabled-child"}}>
+              {{#link-to 'adminCustomizeThemes.show' child replace=true class='col child-link'}}
+                {{child.name}}
+              {{/link-to}}
+
+              {{d-button action=(action "removeChildTheme") actionParam=child class="btn-default cancel-edit col" icon="times"}}
+            </li>
           {{/each}}
         </ul>
       {{/if}}
@@ -221,5 +247,22 @@
   <a class="btn btn-default export" target="_blank" href={{downloadUrl}}>{{d-icon "download"}} {{i18n 'admin.export_json.button_text'}}</a>
 
   {{d-button action=(action "switchType") label="admin.customize.theme.convert" icon=convertIcon class="btn-default btn-normal" title=convertTooltip}}
+
+  {{#if model.component}}
+    {{#if model.enabled}}
+      {{d-button
+        class='btn-default'
+        action=(action "disableComponent")
+        icon="ban"
+        label="admin.customize.theme.disable"}}
+    {{else}}
+      {{d-button
+        class='btn-default'
+        action=(action "enableComponent")
+        icon="check"
+        label="admin.customize.theme.enable"}}
+    {{/if}}
+  {{/if}}
+
   {{d-button action=(action "destroy") label="admin.customize.delete" icon="trash-alt" class="btn-danger"}}
 </div>
diff --git a/app/assets/stylesheets/common/admin/customize.scss b/app/assets/stylesheets/common/admin/customize.scss
index 15136dd..86290bc 100644
--- a/app/assets/stylesheets/common/admin/customize.scss
+++ b/app/assets/stylesheets/common/admin/customize.scss
@@ -513,8 +513,19 @@
     list-style: none;
     margin-left: 0;
     li {
+      &.disabled-child {
+        .child-link {
+          color: $primary-medium;
+          &:hover {
+            text-decoration: underline;
+          }
+        }
+      }
+      .btn {
+        margin-left: 5px;
+      }
       display: table-row;
-      .col:first-child {
+      .col.child-link {
         padding-right: 10px;
         padding-bottom: 10px;
         min-width: 80px;
diff --git a/app/controllers/admin/themes_controller.rb b/app/controllers/admin/themes_controller.rb
index 4684ebe..5389269 100644
--- a/app/controllers/admin/themes_controller.rb
+++ b/app/controllers/admin/themes_controller.rb
@@ -156,8 +156,10 @@ class Admin::ThemesController < Admin::AdminController
     raise Discourse::InvalidParameters.new(:id) unless @theme
 
     original_json = ThemeSerializer.new(@theme, root: false).to_json
+    disables_component = [false, "false"].include?(theme_params[:enabled])
+    enables_component = [true, "true"].include?(theme_params[:enabled])
 
-    [:name, :color_scheme_id, :user_selectable].each do |field|
+    [:name, :color_scheme_id, :user_selectable, :enabled].each do |field|
       if theme_params.key?(field)
         @theme.public_send("#{field}=", theme_params[field])
       end
@@ -203,7 +205,13 @@ class Admin::ThemesController < Admin::AdminController
         update_default_theme
 
         @theme.reload
-        log_theme_change(original_json, @theme)
+
+        if (!disables_component && !enables_component) || theme_params.keys.size > 1
+          log_theme_change(original_json, @theme)
+        end
+        log_theme_component_disabled if disables_component
+        log_theme_component_enabled if enables_component
+

[... diff too long, it was truncated ...]

GitHub sha: 3d645322

1 Like