UX: Revamp quick search (#14499)

UX: Revamp quick search (#14499)

Co-authored-by: Robin Ward robin.ward@gmail.com Co-authored-by: Alan Guo Xiang Tan gxtan1990@gmail.com

diff --git a/app/assets/javascripts/discourse/app/lib/search.js b/app/assets/javascripts/discourse/app/lib/search.js
index eb2e829..5df67d4 100644
--- a/app/assets/javascripts/discourse/app/lib/search.js
+++ b/app/assets/javascripts/discourse/app/lib/search.js
@@ -117,11 +117,8 @@ function translateGroupedSearchResults(results, opts) {
       const name = pair[1];
       if (results[name].length > 0) {
         const componentName =
-          opts.searchContext &&
-          opts.searchContext.type === "topic" &&
-          type === "topic"
-            ? "post"
-            : type;
+          opts.showPosts && type === "topic" ? "post" : type;
+
         const result = {
           results: results[name],
           componentName: `search-result-${componentName}`,
@@ -157,12 +154,8 @@ export function searchForTerm(term, opts) {
     data.restrict_to_archetype = opts.restrictToArchetype;
   }
 
-  if (opts.searchContext) {
-    data.search_context = {
-      type: opts.searchContext.type,
-      id: opts.searchContext.id,
-      name: opts.searchContext.name,
-    };
+  if (term.includes("topic:")) {
+    opts.showPosts = true;
   }
 
   let ajaxPromise = ajax("/search/query", { data });
diff --git a/app/assets/javascripts/discourse/app/services/search.js b/app/assets/javascripts/discourse/app/services/search.js
index 87a77b7..7546dd1 100644
--- a/app/assets/javascripts/discourse/app/services/search.js
+++ b/app/assets/javascripts/discourse/app/services/search.js
@@ -1,17 +1,11 @@
 import EmberObject, { get } from "@ember/object";
-import discourseComputed, { observes } from "discourse-common/utils/decorators";
+import discourseComputed from "discourse-common/utils/decorators";
 
 export default EmberObject.extend({
   searchContextEnabled: false, // checkbox to scope search
   searchContext: null,
-  term: null,
   highlightTerm: null,
 
-  @observes("term")
-  _sethighlightTerm() {
-    this.set("highlightTerm", this.term);
-  },
-
   @discourseComputed("searchContext")
   contextType: {
     get(searchContext) {
diff --git a/app/assets/javascripts/discourse/app/widgets/search-menu-controls.js b/app/assets/javascripts/discourse/app/widgets/search-menu-controls.js
index b01dd15..f6aed4e 100644
--- a/app/assets/javascripts/discourse/app/widgets/search-menu-controls.js
+++ b/app/assets/javascripts/discourse/app/widgets/search-menu-controls.js
@@ -1,34 +1,21 @@
 import I18n from "I18n";
 import { createWidget } from "discourse/widgets/widget";
-import { get } from "@ember/object";
-import { h } from "virtual-dom";
-import { searchContextDescription } from "discourse/lib/search";
 
 createWidget("search-term", {
   tagName: "input",
   buildId: () => "search-term",
   buildKey: () => "search-term",
 
-  defaultState() {
-    return { afterAutocomplete: false };
-  },
-
   buildAttributes(attrs) {
     return {
       type: "text",
       value: attrs.value || "",
-      autocomplete: "discourse",
-      placeholder: attrs.contextEnabled ? "" : I18n.t("search.title"),
+      autocomplete: "off",
+      placeholder: I18n.t("search.title"),
       "aria-label": I18n.t("search.title"),
     };
   },
 
-  keyUp(e) {
-    if (e.key === "Enter" && !this.state.afterAutocomplete) {
-      return this.sendWidgetAction("fullSearch");
-    }
-  },
-
   input(e) {
     const val = this.attrs.value;
 
@@ -41,47 +28,9 @@ createWidget("search-term", {
   },
 });
 
+// TODO: No longer used, remove in December 2021
 createWidget("search-context", {
-  tagName: "div.search-context",
-
-  html(attrs) {
-    const service = this.register.lookup("search-service:main");
-    const ctx = service.get("searchContext");
-
-    const result = [];
-    if (ctx) {
-      const description = searchContextDescription(
-        get(ctx, "type"),
-        get(ctx, "user.username") ||
-          get(ctx, "category.name") ||
-          get(ctx, "tag.id")
-      );
-      result.push(
-        h("label", [
-          h("input", { type: "checkbox", checked: attrs.contextEnabled }),
-          " ",
-          description,
-        ])
-      );
-    }
-
-    if (!attrs.contextEnabled) {
-      result.push(
-        this.attach("link", {
-          href: attrs.url,
-          label: "show_help",
-          className: "show-help",
-        })
-      );
-    }
-
-    return result;
-  },
-
-  click() {
-    const val = $(".search-context input").is(":checked");
-    if (val !== this.attrs.contextEnabled) {
-      this.sendWidgetAction("searchContextChanged", val);
-    }
+  html() {
+    return false;
   },
 });
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 ca01d7e..cf435b7 100644
--- a/app/assets/javascripts/discourse/app/widgets/search-menu-results.js
+++ b/app/assets/javascripts/discourse/app/widgets/search-menu-results.js
@@ -1,4 +1,5 @@
 import { escapeExpression, formatUsername } from "discourse/lib/utilities";
+import { deepMerge } from "discourse-common/lib/object";
 import I18n from "I18n";
 import RawHtml from "discourse/widgets/raw-html";
 import { avatarImg } from "discourse/widgets/post";
@@ -10,6 +11,10 @@ import { h } from "virtual-dom";
 import highlightSearch from "discourse/lib/highlight-search";
 import { iconNode } from "discourse-common/lib/icon-library";
 import renderTag from "discourse/lib/render-tag";
+import {
+  MODIFIER_REGEXP,
+  TOPIC_REPLACE_REGEXP,
+} from "discourse/widgets/search-menu";
 
 const suggestionShortcuts = [
   "in:title",
@@ -24,6 +29,29 @@ const suggestionShortcuts = [
   "order:latest_topic",
 ];
 
+const QUICK_TIPS = [
+  {
+    label: "#",
+    description: I18n.t("search.tips.category_tag"),
+  },
+  {
+    label: "@",
+    description: I18n.t("search.tips.author"),
+  },
+  {
+    label: "in:",
+    description: I18n.t("search.tips.in"),
+  },
+  {
+    label: "status:",
+    description: I18n.t("search.tips.status"),
+  },
+  {
+    label: I18n.t("search.tips.full_search_key", { modifier: "Ctrl" }),
+    description: I18n.t("search.tips.full_search"),
+  },
+];
+
 export function addSearchSuggestion(value) {
   if (suggestionShortcuts.indexOf(value) === -1) {
     suggestionShortcuts.push(value);
@@ -33,7 +61,7 @@ export function addSearchSuggestion(value) {
 class Highlighted extends RawHtml {
   constructor(html, term) {
     super({ html: `<span>${html}</span>` });
-    this.term = term;
+    this.term = term.replace(TOPIC_REPLACE_REGEXP, "");
   }
 
   decorate($html) {
@@ -63,7 +91,6 @@ function createSearchResult({ type, linkField, builder }) {
             className: "search-link",
             searchResultId,
             searchResultType: type,
-            searchContextEnabled: attrs.searchContextEnabled,
             searchLogId: attrs.searchLogId,
           })
         );
@@ -95,7 +122,10 @@ createSearchResult({
   linkField: "url",
   builder(t) {
     const tag = escapeExpression(t.id);
-    return new RawHtml({ html: renderTag(tag, { tagName: "span" }) });
+    return [
+      iconNode("tag"),
+      new RawHtml({ html: renderTag(tag, { tagName: "span" }) }),
+    ];
   },
 });
 
@@ -227,84 +257,82 @@ createWidget("search-menu-results", {
   tagName: "div.results",
 
   html(attrs) {
-    if (attrs.suggestionKeyword) {
+    const { term, suggestionKeyword, results, searchTopics } = attrs;
+
+    if (suggestionKeyword) {
       return this.attach("search-menu-assistant", {
-        fullTerm: attrs.term,
-        suggestionKeyword: attrs.suggestionKeyword,
+        term,
+        suggestionKeyword,
         results: attrs.suggestionResults || [],
       });
     }
 
-    if (attrs.invalidTerm) {
+    if (searchTopics && attrs.invalidTerm) {
       return h("div.no-results", I18n.t("search.too_short"));
     }
 
-    if (attrs.noResults) {
+    if (searchTopics && attrs.noResults) {
       return h("div.no-results", I18n.t("search.no_results"));
     }
 
-    const results = attrs.results;
+    if (!term) {

[... diff too long, it was truncated ...]

GitHub sha: e9b1d29d8bac50abc5997b552457086f3a66462e

This commit appears in #14499 which was approved by eviltrout and tgxworld. It was merged by pmusaraj.