DEV: Add pluginApi support for quick search tips (#14556)

DEV: Add pluginApi support for quick search tips (#14556)

diff --git a/app/assets/javascripts/discourse/app/lib/plugin-api.js b/app/assets/javascripts/discourse/app/lib/plugin-api.js
index 1c8c48c..ed86e5d 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) {
@@ -1424,6 +1427,25 @@ class PluginApi {
   }
 
   /**
+   * 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.
    * Example usage:
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 fda5656..4d8c4fb 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: `<span>${html}</span>` });
@@ -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 f2e1bd1..b62a4ae 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 070fbd3..e5e71d4 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 b9c7759..63e84a9 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;
+        }
       }
     }
   }

GitHub sha: 915c93625a17e75530a6108145d9e22035c9ae03

This commit appears in #14556 which was approved by eviltrout. It was merged by pmusaraj.