UX: shows a hint when there are more tags than displayed (#12649)

UX: shows a hint when there are more tags than displayed (#12649)

diff --git a/app/assets/javascripts/select-kit/addon/components/tag-drop.js b/app/assets/javascripts/select-kit/addon/components/tag-drop.js
index e28079a..16fb2ca 100644
--- a/app/assets/javascripts/select-kit/addon/components/tag-drop.js
+++ b/app/assets/javascripts/select-kit/addon/components/tag-drop.js
@@ -5,11 +5,14 @@ import DiscourseURL, { getCategoryAndTagUrl } from "discourse/lib/url";
 import TagsMixin from "select-kit/mixins/tags";
 import { computed } from "@ember/object";
 import { makeArray } from "discourse-common/lib/helpers";
+import { MAIN_COLLECTION } from "select-kit/components/select-kit";
 
 export const NO_TAG_ID = "no-tags";
 export const ALL_TAGS_ID = "all-tags";
 export const NONE_TAG_ID = "none";
 
+const MORE_TAGS_COLLECTION = "MORE_TAGS_COLLECTION";
+
 export default ComboBoxComponent.extend(TagsMixin, {
   pluginApiIdentifiers: ["tag-drop"],
   classNameBindings: ["categoryStyle", "tagClass"],
@@ -19,6 +22,14 @@ export default ComboBoxComponent.extend(TagsMixin, {
   categoryStyle: setting("category_style"),
   maxTagSearchResults: setting("max_tag_search_results"),
   sortTagsAlphabetically: setting("tags_sort_alphabetically"),
+  maxTagsInFilterList: setting("max_tags_in_filter_list"),
+  shouldShowMoreTags: computed(
+    "maxTagsInFilterList",
+    "topTags.[]",
+    function () {
+      return this.topTags.length > this.maxTagsInFilterList;
+    }
+  ),
 
   selectKitOptions: {
     allowAny: false,
@@ -34,6 +45,26 @@ export default ComboBoxComponent.extend(TagsMixin, {
 
   filterable: gte("content.length", 15),
 
+  init() {
+    this._super(...arguments);
+
+    this.insertAfterCollection(MAIN_COLLECTION, MORE_TAGS_COLLECTION);
+  },
+
+  modifyComponentForCollection(collection) {
+    if (collection === MORE_TAGS_COLLECTION) {
+      return "tag-drop/more-tags-collection";
+    }
+  },
+
+  modifyContentForCollection(collection) {
+    if (collection === MORE_TAGS_COLLECTION) {
+      return {
+        shouldShowMoreTags: this.shouldShowMoreTags,
+      };
+    }
+  },
+
   modifyNoSelection() {
     if (this.noTagsSelected) {
       return this.defaultItem(NO_TAG_ID, this.noTagsLabel);
@@ -90,18 +121,19 @@ export default ComboBoxComponent.extend(TagsMixin, {
     "site.top_tags.[]",
     function () {
       if (this.currentCategory && this.site.category_top_tags) {
-        return this.site.category_top_tags;
+        return this.site.category_top_tags || [];
       }
 
-      return this.site.top_tags;
+      return this.site.top_tags || [];
     }
   ),
 
   content: computed("topTags.[]", "shortcuts.[]", function () {
-    if (this.sortTagsAlphabetically && this.topTags) {
-      return this.shortcuts.concat(this.topTags.sort());
+    const topTags = this.topTags.slice(0, this.maxTagsInFilterList);
+    if (this.sortTagsAlphabetically && topTags) {
+      return this.shortcuts.concat(topTags.sort());
     } else {
-      return this.shortcuts.concat(makeArray(this.topTags));
+      return this.shortcuts.concat(makeArray(topTags));
     }
   }),
 
diff --git a/app/assets/javascripts/select-kit/addon/components/tag-drop/more-tags-collection.js b/app/assets/javascripts/select-kit/addon/components/tag-drop/more-tags-collection.js
new file mode 100644
index 0000000..af08653
--- /dev/null
+++ b/app/assets/javascripts/select-kit/addon/components/tag-drop/more-tags-collection.js
@@ -0,0 +1,10 @@
+import Component from "@ember/component";
+import layout from "select-kit/templates/components/tag-drop/more-tags-collection";
+
+export default Component.extend({
+  tagName: "",
+
+  layout,
+
+  collection: null,
+});
diff --git a/app/assets/javascripts/select-kit/addon/templates/components/tag-drop/more-tags-collection.hbs b/app/assets/javascripts/select-kit/addon/templates/components/tag-drop/more-tags-collection.hbs
new file mode 100644
index 0000000..fe381b4
--- /dev/null
+++ b/app/assets/javascripts/select-kit/addon/templates/components/tag-drop/more-tags-collection.hbs
@@ -0,0 +1,5 @@
+{{#if collection.content.shouldShowMoreTags}}
+  <div class="more-tags">
+    {{i18n "select_kit.components.tag_drop.filter_for_more"}}
+  </div>
+{{/if}}
diff --git a/app/assets/stylesheets/common/select-kit/tag-drop.scss b/app/assets/stylesheets/common/select-kit/tag-drop.scss
index 382c378..09d456c 100644
--- a/app/assets/stylesheets/common/select-kit/tag-drop.scss
+++ b/app/assets/stylesheets/common/select-kit/tag-drop.scss
@@ -10,6 +10,15 @@
           font-weight: 700;
         }
       }
+
+      .more-tags {
+        display: flex;
+        box-sizing: border-box;
+        width: 100%;
+        padding: 0.5em 1em;
+        font-size: $font-down-1;
+        color: var(--primary-low-mid);
+      }
     }
   }
 }
diff --git a/app/models/tag.rb b/app/models/tag.rb
index 5245843..78b30fb 100644
--- a/app/models/tag.rb
+++ b/app/models/tag.rb
@@ -95,7 +95,9 @@ class Tag < ActiveRecord::Base
   end
 
   def self.top_tags(limit_arg: nil, category: nil, guardian: nil)
-    limit = limit_arg || SiteSetting.max_tags_in_filter_list
+    # we add 1 to max_tags_in_filter_list to efficiently know we have more tags
+    # than the limit. Frontend is responsible to enforce limit.
+    limit = limit_arg || (SiteSetting.max_tags_in_filter_list + 1)
     scope_category_ids = (guardian || Guardian.new).allowed_category_ids
 
     if category
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index c1e0274..9a30d8c 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -1919,6 +1919,8 @@ en:
         one: "Selection must be at least %{count} character."
         other: "Selection must be at least %{count} characters."
       components:
+        tag_drop:
+          filter_for_more: Filter for more...
         categories_admin_dropdown:
           title: "Manage categories"
 

GitHub sha: 081ada09

This commit appears in #12649 which was approved by CvX. It was merged by jjaffeux.