DEV: Allow the creation of sub-sub-categories

DEV: Allow the creation of sub-sub-categories

This commits adds a new site setting (max_category_nesting), that determines whether sub-sub-categories are allowable.

diff --git a/app/assets/javascripts/discourse/components/edit-category-general.js.es6 b/app/assets/javascripts/discourse/components/edit-category-general.js.es6
index bdcdf440dc..9d3e548a20 100644
--- a/app/assets/javascripts/discourse/components/edit-category-general.js.es6
+++ b/app/assets/javascripts/discourse/components/edit-category-general.js.es6
@@ -61,7 +61,7 @@ export default buildCategoryPanel("general", {
   parentCategories() {
     return this.site
       .get("categoriesList")
-      .filter(c => !c.get("parentCategory"));
+      .filter(c => c.level + 1 < Discourse.SiteSettings.max_category_nesting);
   },
 
   @discourseComputed(
diff --git a/app/assets/javascripts/discourse/models/category.js.es6 b/app/assets/javascripts/discourse/models/category.js.es6
index 1b442db7c5..9bb56c276e 100644
--- a/app/assets/javascripts/discourse/models/category.js.es6
+++ b/app/assets/javascripts/discourse/models/category.js.es6
@@ -60,6 +60,11 @@ const Category = RestModel.extend({
     return [...(parentAncestors || []), this];
   },
 
+  @discourseComputed("parentCategory.level")
+  level(parentLevel) {
+    return (parentLevel || -1) + 1;
+  },
+
   @discourseComputed("notification_level")
   isMuted(notificationLevel) {
     return notificationLevel === NotificationLevels.MUTED;
diff --git a/app/assets/javascripts/discourse/templates/components/edit-category-general.hbs b/app/assets/javascripts/discourse/templates/components/edit-category-general.hbs
index 5f0720e838..1c30b0c762 100644
--- a/app/assets/javascripts/discourse/templates/components/edit-category-general.hbs
+++ b/app/assets/javascripts/discourse/templates/components/edit-category-general.hbs
@@ -22,7 +22,7 @@
           value=category.parent_category_id
           excludeCategoryId=category.id
           categories=parentCategories
-          allowSubCategories=false
+          allowSubCategories=true
           allowUncategorized=false}}
       {{/if}}
     </section>
diff --git a/app/models/category.rb b/app/models/category.rb
index 25aeff75fc..5af5eabac3 100644
--- a/app/models/category.rb
+++ b/app/models/category.rb
@@ -13,7 +13,6 @@ class Category < ActiveRecord::Base
   include AnonCacheInvalidator
   include HasDestroyedWebHook
 
-  MAX_NESTING = 2 # category + subcategory
   REQUIRE_TOPIC_APPROVAL = 'require_topic_approval'
   REQUIRE_REPLY_APPROVAL = 'require_reply_approval'
   NUM_AUTO_BUMP_DAILY = 'num_auto_bump_daily'
@@ -329,7 +328,7 @@ class Category < ActiveRecord::Base
 
   # This is used in a validation so has to produce accurate results before the
   # record has been saved
-  def height_of_ancestors(max_height = MAX_NESTING)
+  def height_of_ancestors(max_height = SiteSetting.max_category_nesting)
     parent_id = self.parent_category_id
 
     return max_height if parent_id == id
@@ -357,7 +356,7 @@ class Category < ActiveRecord::Base
 
   # This is used in a validation so has to produce accurate results before the
   # record has been saved
-  def depth_of_descendants(max_depth = MAX_NESTING)
+  def depth_of_descendants(max_depth = SiteSetting.max_category_nesting)
     parent_id = self.parent_category_id
 
     return max_depth if parent_id == id
@@ -390,7 +389,7 @@ class Category < ActiveRecord::Base
       errors.add(:base, I18n.t("category.errors.self_parent")) if parent_category_id == id
 
       total_depth = height_of_ancestors + 1 + depth_of_descendants
-      errors.add(:base, I18n.t("category.errors.depth")) if total_depth > MAX_NESTING
+      errors.add(:base, I18n.t("category.errors.depth")) if total_depth > SiteSetting.max_category_nesting
     end
   end
 
diff --git a/config/site_settings.yml b/config/site_settings.yml
index 103194d78a..9d1f045f0c 100644
--- a/config/site_settings.yml
+++ b/config/site_settings.yml
@@ -240,6 +240,12 @@ basic:
       - box
       - bullet
       - none
+  max_category_nesting:
+    client: true
+    default: 2
+    min: 2
+    max: 3
+    hidden: true
   enable_mobile_theme:
     client: true
     default: true

GitHub sha: 2f5adbe1

1 Like