diff --git a/app/assets/javascripts/admin/adapters/theme.js.es6 b/app/assets/javascripts/admin/adapters/theme.js.es6
index b98ba3e4230..8609df240bd 100644
--- a/app/assets/javascripts/admin/adapters/theme.js.es6
+++ b/app/assets/javascripts/admin/adapters/theme.js.es6
@@ -14,6 +14,10 @@ export default RestAdapter.extend({
let mapped = theme.get("child_themes") || [];
mapped = mapped.map(t => map[t.id]);
theme.set("childThemes", mapped);
+
+ let mappedParents = theme.get("parent_themes") || [];
+ mappedParents = mappedParents.map(t => map[t.id]);
+ theme.set("parentThemes", mappedParents);
});
return results;
},
diff --git a/app/assets/javascripts/admin/components/themes-list.js.es6 b/app/assets/javascripts/admin/components/themes-list.js.es6
index abb03af476d..00b7af61547 100644
--- a/app/assets/javascripts/admin/components/themes-list.js.es6
+++ b/app/assets/javascripts/admin/components/themes-list.js.es6
@@ -8,7 +8,7 @@ export default Ember.Component.extend({
classNames: ["themes-list"],
hasThemes: Ember.computed.gt("themesList.length", 0),
- hasUserThemes: Ember.computed.gt("userThemes.length", 0),
+ hasActiveThemes: Ember.computed.gt("activeThemes.length", 0),
hasInactiveThemes: Ember.computed.gt("inactiveThemes.length", 0),
themesTabActive: Ember.computed.equal("currentTab", THEMES),
@@ -31,7 +31,7 @@ export default Ember.Component.extend({
)
inactiveThemes(themes) {
if (this.get("componentsTabActive")) {
- return [];
+ return themes.filter(theme => theme.get("parentThemes.length") <= 0);
}
return themes.filter(
theme => !theme.get("user_selectable") && !theme.get("default")
@@ -44,20 +44,21 @@ export default Ember.Component.extend({
"themesList.@each.user_selectable",
"themesList.@each.default"
)
- userThemes(themes) {
+ activeThemes(themes) {
if (this.get("componentsTabActive")) {
- return [];
+ return themes.filter(theme => theme.get("parentThemes.length") > 0);
+ } else {
+ themes = themes.filter(
+ theme => theme.get("user_selectable") || theme.get("default")
+ );
+ return _.sortBy(themes, t => {
+ return [
+ !t.get("default"),
+ !t.get("user_selectable"),
+ t.get("name").toLowerCase()
+ ];
+ });
}
- themes = themes.filter(
- theme => theme.get("user_selectable") || theme.get("default")
- );
- return _.sortBy(themes, t => {
- return [
- !t.get("default"),
- !t.get("user_selectable"),
- t.get("name").toLowerCase()
- ];
- });
},
didRender() {
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 5b67d6d40d9..38d73d534f6 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
@@ -13,17 +13,6 @@ export default Ember.Controller.extend({
addButtonDisabled: Ember.computed.empty("selectedChildThemeId"),
editRouteName: "adminCustomizeThemes.edit",
- @computed("model", "allThemes", "model.component")
- parentThemes(model, allThemes) {
- if (!model.get("component")) {
- return null;
- }
- const parents = allThemes.filter(theme =>
- _.contains(theme.get("childThemes"), model)
- );
- return parents.length === 0 ? null : parents;
- },
-
@computed("model.editedFields")
editedFieldsFormatted() {
const descriptions = [];
diff --git a/app/assets/javascripts/admin/templates/components/themes-list.hbs b/app/assets/javascripts/admin/templates/components/themes-list.hbs
index 6a553a9450a..eff53727149 100644
--- a/app/assets/javascripts/admin/templates/components/themes-list.hbs
+++ b/app/assets/javascripts/admin/templates/components/themes-list.hbs
@@ -9,32 +9,32 @@
{{#if hasThemes}}
- {{#if componentsTabActive}}
- {{#each themesList as |theme|}}
+ {{#if hasActiveThemes}}
+ {{#each activeThemes as |theme|}}
{{themes-list-item theme=theme navigateToTheme=(action "navigateToTheme" theme)}}
{{/each}}
- {{else}}
- {{#if hasUserThemes}}
- {{#each userThemes as |theme|}}
- {{themes-list-item theme=theme navigateToTheme=(action "navigateToTheme" theme)}}
- {{/each}}
-
- {{#if hasInactiveThemes}}
-
- {{I18n "admin.customize.theme.inactive_themes"}}
-
- {{/if}}
- {{/if}}
{{#if hasInactiveThemes}}
- {{#each inactiveThemes as |theme|}}
- {{themes-list-item theme=theme navigateToTheme=(action "navigateToTheme" theme)}}
- {{/each}}
+
+
+ {{#if themesTabActive}}
+ {{I18n "admin.customize.theme.inactive_themes"}}
+ {{else}}
+ {{I18n "admin.customize.theme.inactive_components"}}
+ {{/if}}
+
+
{{/if}}
{{/if}}
+
+ {{#if hasInactiveThemes}}
+ {{#each inactiveThemes as |theme|}}
+ {{themes-list-item theme=theme navigateToTheme=(action "navigateToTheme" theme)}}
+ {{/each}}
+ {{/if}}
{{else}}
{{I18n "admin.customize.theme.empty"}}
{{/if}}
-
+
\ No newline at end of file
diff --git a/app/assets/javascripts/admin/templates/customize-themes-show.hbs b/app/assets/javascripts/admin/templates/customize-themes-show.hbs
index 4fc19567623..47dab4dda6b 100644
--- a/app/assets/javascripts/admin/templates/customize-themes-show.hbs
+++ b/app/assets/javascripts/admin/templates/customize-themes-show.hbs
@@ -26,11 +26,11 @@
{{/if}}
{{/if}}
- {{#if parentThemes}}
+ {{#if model.parentThemes}}
{{i18n "admin.customize.theme.component_of"}}
- {{#each parentThemes as |theme|}}
+ {{#each model.parentThemes as |theme|}}
- {{#link-to 'adminCustomizeThemes.show' theme replace=true}}{{theme.name}}{{/link-to}}
{{/each}}
diff --git a/app/controllers/admin/themes_controller.rb b/app/controllers/admin/themes_controller.rb
index 68016925060..45600be14c3 100644
--- a/app/controllers/admin/themes_controller.rb
+++ b/app/controllers/admin/themes_controller.rb
@@ -97,6 +97,7 @@ class Admin::ThemesController < Admin::AdminController
def index
@themes = Theme.order(:name).includes(:child_themes,
+ :parent_themes,
:remote_theme,
:theme_settings,
:settings_field,
diff --git a/app/models/theme.rb b/app/models/theme.rb
index cbb37e108af..7db8dcf2231 100644
--- a/app/models/theme.rb
+++ b/app/models/theme.rb
@@ -19,7 +19,9 @@ class Theme < ActiveRecord::Base
has_many :theme_settings, dependent: :destroy
has_many :theme_translation_overrides, dependent: :destroy
has_many :child_theme_relation, class_name: 'ChildTheme', foreign_key: 'parent_theme_id', dependent: :destroy
+ has_many :parent_theme_relation, class_name: 'ChildTheme', foreign_key: 'child_theme_id', dependent: :destroy
has_many :child_themes, -> { order(:name) }, through: :child_theme_relation, source: :child_theme
+ has_many :parent_themes, -> { order(:name) }, through: :parent_theme_relation, source: :parent_theme
has_many :color_schemes
belongs_to :remote_theme
diff --git a/app/serializers/theme_serializer.rb b/app/serializers/theme_serializer.rb
index bc2e1de0f9b..7e4110c72a4 100644
--- a/app/serializers/theme_serializer.rb
+++ b/app/serializers/theme_serializer.rb
@@ -32,7 +32,7 @@ class ThemeFieldSerializer < ApplicationSerializer
end
end
-class ChildThemeSerializer < ApplicationSerializer
+class BasicThemeSerializer < ApplicationSerializer
attributes :id, :name, :created_at, :updated_at, :default, :component
def include_default?
@@ -60,13 +60,14 @@ class RemoteThemeSerializer < ApplicationSerializer
end
end
-class ThemeSerializer < ChildThemeSerializer
+class ThemeSerializer < BasicThemeSerializer
attributes :color_scheme, :color_scheme_id, :user_selectable, :remote_theme_id, :settings, :errors
has_one :user, serializer: UserNameSerializer, embed: :object
has_many :theme_fields, serializer: ThemeFieldSerializer, embed: :objects
- has_many :child_themes, serializer: ChildThemeSerializer, embed: :objects
+ has_many :child_themes, serializer: BasicThemeSerializer, embed: :objects
+ has_many :parent_themes, serializer: BasicThemeSerializer, embed: :objects
has_one :remote_theme, serializer: RemoteThemeSerializer, embed: :objects
has_many :translations, serializer: ThemeTranslationSerializer, embed: :objects
@@ -79,6 +80,10 @@ class ThemeSerializer < ChildThemeSerializer
object.child_themes
end
+ def parent_themes
+ object.parent_themes
+ end
+
def settings
object.settings.map { |setting| ThemeSettingsSerializer.new(setting, root: false) }
rescue ThemeSettingsParser::InvalidYaml => e
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index b046424a6eb..684a54fea98 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -3356,6 +3356,7 @@ en:
convert_theme_alert: "Are you sure you want to convert this theme to component? It will be removed as a parent from %{relatives}."
convert_theme_tooltip: "Convert this theme to component"
inactive_themes: "Inactive themes:"
+ inactive_components: "Unused components:"
broken_theme_tooltip: "This theme has errors in its CSS, HTML or YAML"
default_theme_tooltip: "This theme is the site's default theme"
updates_available_tooltip: "Updates are available for this theme"
diff --git a/test/javascripts/admin/components/themes-list-test.js.es6 b/test/javascripts/admin/components/themes-list-test.js.es6
index 040b9772b6a..2a1c58849fc 100644
--- a/test/javascripts/admin/components/themes-list-test.js.es6
+++ b/test/javascripts/admin/components/themes-list-test.js.es6
@@ -7,7 +7,11 @@ const themes = [1, 2, 3, 4, 5].map(num =>
Theme.create({ name: `Theme ${num}` })
);
const components = [1, 2, 3, 4, 5].map(num =>
- Theme.create({ name: `Child ${num}`, component: true })
+ Theme.create({
+ name: `Child ${num}`,
+ component: true,
+ parentThemes: [themes[num - 1]]
+ })
);
componentTest("current tab is themes", {