diff --git a/app/assets/javascripts/discourse/helpers/category-link.js.es6 b/app/assets/javascripts/discourse/helpers/category-link.js.es6 index 3cdb03c8f00..b32c0c94522 100644 --- a/app/assets/javascripts/discourse/helpers/category-link.js.es6 +++ b/app/assets/javascripts/discourse/helpers/category-link.js.es6 @@ -25,7 +25,9 @@ function categoryStripe(color, classes) { @param {String} [opts.url] The url that we want the category badge to link to. @param {Boolean} [opts.allowUncategorized] If false, returns an empty string for the uncategorized category. @param {Boolean} [opts.link] If false, the category badge will not be a link. - @param {Boolean} [opts.hideParaent] If true, parent category will be hidden in the badge. + @param {Boolean} [opts.hideParent] If true, parent category will be hidden in the badge. + @param {Boolean} [opts.recursive] If true, the function will be called recursively for all parent categories + @param {Number} [opts.depth] Current category depth, used for limiting recursive calls **/ export function categoryBadgeHTML(category, opts) { opts = opts || {}; @@ -38,6 +40,13 @@ export function categoryBadgeHTML(category, opts) { ) return ""; + const depth = (opts.depth || 1) + 1; + if (opts.recursive && depth <= Discourse.SiteSettings.max_category_nesting) { + const parentCategory = Category.findById(category.parent_category_id); + opts.depth = depth; + return categoryBadgeHTML(parentCategory, opts) + _renderer(category, opts); + } + return _renderer(category, opts); } diff --git a/app/assets/javascripts/select-kit/components/category-chooser.js.es6 b/app/assets/javascripts/select-kit/components/category-chooser.js.es6 index 43f690b1133..07872a02ce5 100644 --- a/app/assets/javascripts/select-kit/components/category-chooser.js.es6 +++ b/app/assets/javascripts/select-kit/components/category-chooser.js.es6 @@ -72,26 +72,12 @@ export default ComboBoxComponent.extend({ if (this.hasSelection) { const category = Category.findById(content.value); - const parentCategoryId = category.get("parent_category_id"); - const hasParentCategory = Ember.isPresent(parentCategoryId); - - let badge = ""; - - if (hasParentCategory) { - const parentCategory = Category.findById(parentCategoryId); - badge += categoryBadgeHTML(parentCategory, { - link: false, - allowUncategorized: true - }).htmlSafe(); - } - - badge += categoryBadgeHTML(category, { + content.label = categoryBadgeHTML(category, { link: false, - hideParent: hasParentCategory ? true : false, - allowUncategorized: true + hideParent: !!category.parent_category_id, + allowUncategorized: true, + recursive: true }).htmlSafe(); - - content.label = badge; } return content; diff --git a/app/assets/javascripts/select-kit/components/category-row.js.es6 b/app/assets/javascripts/select-kit/components/category-row.js.es6 index dee781b2942..452aad22d53 100644 --- a/app/assets/javascripts/select-kit/components/category-row.js.es6 +++ b/app/assets/javascripts/select-kit/components/category-row.js.es6 @@ -45,7 +45,7 @@ export default SelectKitRowComponent.extend({ return categoryBadgeHTML(category, { link: this.categoryLink, allowUncategorized: this.allowUncategorized, - hideParent: parentCategory ? true : false + hideParent: !!parentCategory }).htmlSafe(); }, @@ -53,7 +53,8 @@ export default SelectKitRowComponent.extend({ badgeForParentCategory(parentCategory) { return categoryBadgeHTML(parentCategory, { link: this.categoryLink, - allowUncategorized: this.allowUncategorized + allowUncategorized: this.allowUncategorized, + recursive: true }).htmlSafe(); }, diff --git a/app/assets/javascripts/select-kit/templates/components/category-row.hbs b/app/assets/javascripts/select-kit/templates/components/category-row.hbs index 94948bc70e7..b35247b47eb 100644 --- a/app/assets/javascripts/select-kit/templates/components/category-row.hbs +++ b/app/assets/javascripts/select-kit/templates/components/category-row.hbs @@ -1,22 +1,15 @@ {{#if category}} - {{#if hasParentCategory}} -
+
+ {{#if hasParentCategory}} {{#unless hideParentCategory}} {{badgeForParentCategory}} {{/unless}} - {{badgeForCategory}} - - × {{topicCount}} - -
- {{else}} -
- {{badgeForCategory}} - - × {{topicCount}} - -
- {{/if}} + {{/if}} + {{badgeForCategory}} + + × {{topicCount}} + +
{{#if shouldDisplayDescription}}
{{{dir-span description}}}
diff --git a/test/javascripts/lib/category-badge-test.js.es6 b/test/javascripts/lib/category-badge-test.js.es6 index 9d0c02e0c52..965899eb11b 100644 --- a/test/javascripts/lib/category-badge-test.js.es6 +++ b/test/javascripts/lib/category-badge-test.js.es6 @@ -91,3 +91,42 @@ QUnit.test("category names are wrapped in dir-spans", assert => { dirSpan = tag.children[1].children[0]; assert.equal(dirSpan.dir, "ltr"); }); + +QUnit.test("recursive", assert => { + const store = createStore(); + + const foo = store.createRecord("category", { + name: "foo", + id: 1 + }); + + const bar = store.createRecord("category", { + name: "bar", + id: 2, + parent_category_id: foo.id + }); + + const baz = store.createRecord("category", { + name: "baz", + id: 3, + parent_category_id: bar.id + }); + + Discourse.set("SiteSettings.max_category_nesting", 0); + assert.ok(categoryBadgeHTML(baz, { recursive: true }).indexOf("baz") !== -1); + assert.ok(categoryBadgeHTML(baz, { recursive: true }).indexOf("bar") === -1); + + Discourse.set("SiteSettings.max_category_nesting", 1); + assert.ok(categoryBadgeHTML(baz, { recursive: true }).indexOf("baz") !== -1); + assert.ok(categoryBadgeHTML(baz, { recursive: true }).indexOf("bar") === -1); + + Discourse.set("SiteSettings.max_category_nesting", 2); + assert.ok(categoryBadgeHTML(baz, { recursive: true }).indexOf("baz") !== -1); + assert.ok(categoryBadgeHTML(baz, { recursive: true }).indexOf("bar") !== -1); + assert.ok(categoryBadgeHTML(baz, { recursive: true }).indexOf("foo") === -1); + + Discourse.set("SiteSettings.max_category_nesting", 3); + assert.ok(categoryBadgeHTML(baz, { recursive: true }).indexOf("baz") !== -1); + assert.ok(categoryBadgeHTML(baz, { recursive: true }).indexOf("bar") !== -1); + assert.ok(categoryBadgeHTML(baz, { recursive: true }).indexOf("foo") !== -1); +});