From 2a6e4a7ba04f5f94d5a295e8989ba0b02511364c Mon Sep 17 00:00:00 2001 From: Bianca Nenciu Date: Thu, 7 Mar 2024 20:46:45 +0200 Subject: [PATCH] FEATURE: Improve "+ subcategories" option (#26086) This commit improves the "+ X subcategories" option that shows sometimes in the category selector. It used to show when there was a single match, but now it also shows up on exact matches even though there are multiple results. It also makes it work when lazy_load_categories is enabled by searching the subcategories before rendering them. --- .../select-kit/category-selector-test.js | 4 +-- .../addon/components/category-row.gjs | 3 ++ .../addon/components/category-selector.js | 36 ++++++++++++------- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/app/assets/javascripts/discourse/tests/integration/components/select-kit/category-selector-test.js b/app/assets/javascripts/discourse/tests/integration/components/select-kit/category-selector-test.js index e7697a6b7f3..ecff80717b3 100644 --- a/app/assets/javascripts/discourse/tests/integration/components/select-kit/category-selector-test.js +++ b/app/assets/javascripts/discourse/tests/integration/components/select-kit/category-selector-test.js @@ -49,8 +49,8 @@ module( "Parent Category × 95" ); assert.equal( - this.subject.rowByIndex(1).el().innerText.replace("\n", " "), - "Parent Category + 2 subcategories" + this.subject.rowByIndex(1).el().innerText.replaceAll("\n", " "), + "Parent Category × 95 + 2 subcategories" ); }); } diff --git a/app/assets/javascripts/select-kit/addon/components/category-row.gjs b/app/assets/javascripts/select-kit/addon/components/category-row.gjs index a03f3b79035..45e047c4d19 100644 --- a/app/assets/javascripts/select-kit/addon/components/category-row.gjs +++ b/app/assets/javascripts/select-kit/addon/components/category-row.gjs @@ -111,6 +111,9 @@ export default class CategoryRow extends Component { this.allowUncategorizedTopics || this.allowUncategorized, hideParent: !!this.parentCategory, topicCount: this.topicCount, + subcategoryCount: this.args.item?.categories + ? this.args.item.categories.length - 1 + : 0, }) ); } diff --git a/app/assets/javascripts/select-kit/addon/components/category-selector.js b/app/assets/javascripts/select-kit/addon/components/category-selector.js index dc1dfe99e3b..896cbed0068 100644 --- a/app/assets/javascripts/select-kit/addon/components/category-selector.js +++ b/app/assets/javascripts/select-kit/addon/components/category-selector.js @@ -1,6 +1,5 @@ import EmberObject, { computed } from "@ember/object"; import { mapBy } from "@ember/object/computed"; -import { categoryBadgeHTML } from "discourse/helpers/category-link"; import Category from "discourse/models/category"; import { makeArray } from "discourse-common/lib/helpers"; import CategoryRow from "select-kit/components/category-row"; @@ -70,19 +69,30 @@ export default MultiSelectComponent.extend({ categories = this._super(filter); } - // If there is a single match and it has subcategories, add a row for - // selecting all - if (categories.length === 1) { - const descendants = categories[0].descendants; - if (descendants.length > 1) { - categories.push( + // If there is a single match or an exact match and it has subcategories, + // add a row for selecting all subcategories + if ( + categories.length === 1 || + (categories.length > 0 && categories[0].name.localeCompare(filter) === 0) + ) { + // Descendants may not be loaded if lazy loading is enabled. Search for + // subcategories will make sure these are loaded + if (this.site.lazy_load_categories) { + await Category.asyncSearch("", { + parentCategoryId: categories[0].id, + }); + } + + if (categories[0].descendants.length > 1) { + categories.splice( + 1, + 0, EmberObject.create({ - label: categoryBadgeHTML(descendants[0], { - link: false, - recursive: true, - subcategoryCount: descendants.length - 1, - }), - categories: [...descendants], + // This is just a hack to ensure the IDs are unique, but ensure + // that parseInt still returns a valid ID in order to generate the + // label + id: `${categories[0].id}+subcategories`, + categories: categories[0].descendants, }) ); }