From 915c93625a17e75530a6108145d9e22035c9ae03 Mon Sep 17 00:00:00 2001 From: Penar Musaraj Date: Tue, 12 Oct 2021 09:54:00 -0400 Subject: [PATCH] DEV: Add pluginApi support for quick search tips (#14556) --- .../discourse/app/lib/plugin-api.js | 26 ++++++++- .../app/widgets/search-menu-results.js | 53 ++++++++++++++++--- .../discourse/app/widgets/search-menu.js | 4 +- .../discourse/tests/helpers/qunit-helpers.js | 2 + .../stylesheets/common/base/search-menu.scss | 3 ++ 5 files changed, 78 insertions(+), 10 deletions(-) diff --git a/app/assets/javascripts/discourse/app/lib/plugin-api.js b/app/assets/javascripts/discourse/app/lib/plugin-api.js index 1c8c48ccebe..ed86e5d8a3d 100644 --- a/app/assets/javascripts/discourse/app/lib/plugin-api.js +++ b/app/assets/javascripts/discourse/app/lib/plugin-api.js @@ -85,11 +85,14 @@ import { replaceFormatter } from "discourse/lib/utilities"; import { replaceTagRenderer } from "discourse/lib/render-tag"; import { setNewCategoryDefaultColors } from "discourse/routes/new-category"; import { addSearchResultsCallback } from "discourse/lib/search"; -import { addSearchSuggestion } from "discourse/widgets/search-menu-results"; +import { + addQuickSearchRandomTip, + addSearchSuggestion, +} from "discourse/widgets/search-menu-results"; import { CUSTOM_USER_SEARCH_OPTIONS } from "select-kit/components/user-chooser"; // If you add any methods to the API ensure you bump up this number -const PLUGIN_API_VERSION = "0.12.5"; +const PLUGIN_API_VERSION = "0.12.6"; // This helper prevents us from applying the same `modifyClass` over and over in test mode. function canModify(klass, type, resolverName, changes) { @@ -1423,6 +1426,25 @@ class PluginApi { addSearchSuggestion(value); } + /** + * Add a quick search tip shown randomly when the search dropdown is invoked on desktop. + * + * Example usage: + * ``` + * const tip = { + * label: "in:docs", + * description: I18n.t("search.tips.in_docs"), + * clickable: true, + * showTopics: true + * }; + * api.addQuickSearchRandomTip(tip); + * ``` + * + */ + addQuickSearchRandomTip(tip) { + addQuickSearchRandomTip(tip); + } + /** * Add custom user search options. * It is heavily correlated with `register_groups_callback_for_users_search_controller_action` which allows defining custom filter. diff --git a/app/assets/javascripts/discourse/app/widgets/search-menu-results.js b/app/assets/javascripts/discourse/app/widgets/search-menu-results.js index fda5656e450..4d8c4fb2eca 100644 --- a/app/assets/javascripts/discourse/app/widgets/search-menu-results.js +++ b/app/assets/javascripts/discourse/app/widgets/search-menu-results.js @@ -29,22 +29,26 @@ const suggestionShortcuts = [ "order:latest_topic", ]; -const QUICK_TIPS = [ +const DEFAULT_QUICK_TIPS = [ { label: "#", description: I18n.t("search.tips.category_tag"), + clickable: true, }, { label: "@", description: I18n.t("search.tips.author"), + clickable: true, }, { label: "in:", description: I18n.t("search.tips.in"), + clickable: true, }, { label: "status:", description: I18n.t("search.tips.status"), + clickable: true, }, { label: I18n.t("search.tips.full_search_key", { modifier: "Ctrl" }), @@ -52,12 +56,26 @@ const QUICK_TIPS = [ }, ]; +let QUICK_TIPS = []; + export function addSearchSuggestion(value) { if (suggestionShortcuts.indexOf(value) === -1) { suggestionShortcuts.push(value); } } +export function addQuickSearchRandomTip(tip) { + if (QUICK_TIPS.indexOf(tip) === -1) { + QUICK_TIPS.push(tip); + } +} + +export function resetQuickSearchRandomTips() { + QUICK_TIPS = [].concat(DEFAULT_QUICK_TIPS); +} + +resetQuickSearchRandomTips(); + class Highlighted extends RawHtml { constructor(html, term) { super({ html: `${html}` }); @@ -609,7 +627,10 @@ createWidget("search-menu-assistant-item", { const searchInput = document.querySelector("#search-term"); searchInput.value = this.attrs.slug; searchInput.focus(); - this.sendWidgetAction("triggerAutocomplete", this.attrs.slug); + this.sendWidgetAction("triggerAutocomplete", { + value: this.attrs.slug, + searchTopics: true, + }); e.preventDefault(); return false; }, @@ -618,11 +639,31 @@ createWidget("search-menu-assistant-item", { createWidget("random-quick-tip", { tagName: "li.search-random-quick-tip", - html() { - const item = QUICK_TIPS[Math.floor(Math.random() * QUICK_TIPS.length)]; + buildKey: () => "random-quick-tip", + + defaultState() { + return QUICK_TIPS[Math.floor(Math.random() * QUICK_TIPS.length)]; + }, + + html(attrs, state) { return [ - h("span.tip-label", item.label), - h("span.tip-description", item.description), + h( + `span.tip-label${state.clickable ? ".tip-clickable" : ""}`, + state.label + ), + h("span.tip-description", state.description), ]; }, + + click(e) { + if (e.target.classList.contains("tip-clickable")) { + const searchInput = document.querySelector("#search-term"); + searchInput.value = this.state.label; + searchInput.focus(); + this.sendWidgetAction("triggerAutocomplete", { + value: this.state.label, + searchTopics: this.state.searchTopics, + }); + } + }, }); diff --git a/app/assets/javascripts/discourse/app/widgets/search-menu.js b/app/assets/javascripts/discourse/app/widgets/search-menu.js index f2e1bd12d05..b62a4ae6451 100644 --- a/app/assets/javascripts/discourse/app/widgets/search-menu.js +++ b/app/assets/javascripts/discourse/app/widgets/search-menu.js @@ -402,8 +402,8 @@ export default createWidget("search-menu", { this.triggerSearch(); }, - triggerAutocomplete(term) { - this.searchTermChanged(term, { searchTopics: true }); + triggerAutocomplete(opts = {}) { + this.searchTermChanged(opts.value, { searchTopics: opts.searchTopics }); }, fullSearch() { diff --git a/app/assets/javascripts/discourse/tests/helpers/qunit-helpers.js b/app/assets/javascripts/discourse/tests/helpers/qunit-helpers.js index 070fbd319f2..e5e71d4ac2f 100644 --- a/app/assets/javascripts/discourse/tests/helpers/qunit-helpers.js +++ b/app/assets/javascripts/discourse/tests/helpers/qunit-helpers.js @@ -38,6 +38,7 @@ import { resetWidgetCleanCallbacks } from "discourse/components/mount-widget"; import { resetUserSearchCache } from "discourse/lib/user-search"; import { resetCardClickListenerSelector } from "discourse/mixins/card-contents-base"; import { resetComposerCustomizations } from "discourse/models/composer"; +import { resetQuickSearchRandomTips } from "discourse/widgets/search-menu-results"; import sessionFixtures from "discourse/tests/fixtures/session-fixtures"; import { setTopicList } from "discourse/lib/topic-list-tracker"; import sinon from "sinon"; @@ -282,6 +283,7 @@ export function acceptance(name, optionsOrCallback) { resetUserSearchCache(); resetCardClickListenerSelector(); resetComposerCustomizations(); + resetQuickSearchRandomTips(); resetPostMenuExtraButtons(); clearNavItems(); setTopicList(null); diff --git a/app/assets/stylesheets/common/base/search-menu.scss b/app/assets/stylesheets/common/base/search-menu.scss index b9c77595a47..63e84a92733 100644 --- a/app/assets/stylesheets/common/base/search-menu.scss +++ b/app/assets/stylesheets/common/base/search-menu.scss @@ -222,6 +222,9 @@ $search-pad-horizontal: 0.5em; margin-right: 4px; padding: 2px 4px; display: inline-block; + &.tip-clickable { + cursor: pointer; + } } } }