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 3aaf47520a6..383075d42ef 100644 --- a/app/assets/javascripts/discourse/app/widgets/search-menu-results.js +++ b/app/assets/javascripts/discourse/app/widgets/search-menu-results.js @@ -380,6 +380,8 @@ createWidget("search-menu-results", { createWidget("search-menu-assistant", { tagName: "ul.search-menu-assistant", + buildKey: () => `search-menu-assistant`, + services: ["router"], html(attrs) { if (this.currentUser) { @@ -434,15 +436,47 @@ createWidget("search-menu-assistant", { }); break; case "@": - attrs.results.forEach((user) => { + // when only one user matches while in topic + // quick suggest user search in the topic or globally + if ( + attrs.results.length === 1 && + this.router.currentRouteName.startsWith("topic.") + ) { + const user = attrs.results[0]; + content.push( + this.attach("search-menu-assistant-item", { + prefix, + user, + setTopicContext: true, + slug: `${prefix}@${user.username}`, + suffix: h( + "span.label-suffix", + ` ${I18n.t("search.in_this_topic")}` + ), + }) + ); content.push( this.attach("search-menu-assistant-item", { prefix, user, slug: `${prefix}@${user.username}`, + suffix: h( + "span.label-suffix", + ` ${I18n.t("search.in_topics_posts")}` + ), }) ); - }); + } else { + attrs.results.forEach((user) => { + content.push( + this.attach("search-menu-assistant-item", { + prefix, + user, + slug: `${prefix}@${user.username}`, + }) + ); + }); + } break; default: suggestionShortcuts.forEach((item) => { @@ -611,6 +645,7 @@ createWidget("search-menu-assistant-item", { username: attrs.user.username, }), h("span.username", formatUsername(attrs.user.username)), + attrs.suffix, ]; content.push(h("span.search-item-user", userResult)); } else { diff --git a/app/assets/javascripts/discourse/tests/acceptance/search-test.js b/app/assets/javascripts/discourse/tests/acceptance/search-test.js index 93787b1a761..673430067a3 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/search-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/search-test.js @@ -27,6 +27,18 @@ acceptance("Search - Anonymous", function (needs) { } return helper.response(searchFixtures["search/query"]); }); + + server.get("/u/search/users", () => { + return helper.response({ + users: [ + { + username: "admin", + name: "admin", + avatar_template: "/images/avatar.png", + }, + ], + }); + }); }); test("search", async function (assert) { @@ -231,6 +243,31 @@ acceptance("Search - Anonymous", function (needs) { ); }); + test("topic search scope - special case when matching a single user", async function (assert) { + await visit("/t/internationalization-localization/280/1"); + + await click("#search-button"); + await fillIn("#search-term", "@admin"); + + assert.equal(count(".search-menu-assistant-item"), 2); + + assert.equal( + query( + ".search-menu-assistant-item:first-child .search-item-user .label-suffix" + ).textContent.trim(), + I18n.t("search.in_this_topic"), + "first result hints in this topic search" + ); + + assert.equal( + query( + ".search-menu-assistant-item:nth-child(2) .search-item-user .label-suffix" + ).textContent.trim(), + I18n.t("search.in_topics_posts"), + "second result hints global search" + ); + }); + test("Right filters are shown in full page search", async function (assert) { const inSelector = selectKit(".select-kit#in");