From 081ada090c494687d32e4f64c262f1b633939e51 Mon Sep 17 00:00:00 2001 From: Joffrey JAFFEUX Date: Thu, 8 Apr 2021 15:51:31 +0200 Subject: [PATCH] UX: shows a hint when there are more tags than displayed (#12649) --- .../select-kit/addon/components/tag-drop.js | 42 ++++++++++++++++--- .../tag-drop/more-tags-collection.js | 10 +++++ .../tag-drop/more-tags-collection.hbs | 5 +++ .../common/select-kit/tag-drop.scss | 9 ++++ app/models/tag.rb | 4 +- config/locales/client.en.yml | 2 + 6 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 app/assets/javascripts/select-kit/addon/components/tag-drop/more-tags-collection.js create mode 100644 app/assets/javascripts/select-kit/addon/templates/components/tag-drop/more-tags-collection.hbs 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 e28079a9423..16fb2ca7892 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 00000000000..af0865396b7 --- /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 00000000000..fe381b427b4 --- /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}} +
+ {{i18n "select_kit.components.tag_drop.filter_for_more"}} +
+{{/if}} diff --git a/app/assets/stylesheets/common/select-kit/tag-drop.scss b/app/assets/stylesheets/common/select-kit/tag-drop.scss index 382c3787321..09d456c59b2 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 5245843e493..78b30fb48ce 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 c1e0274bfb3..9a30d8ced3e 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"