diff --git a/app/assets/javascripts/discourse/app/components/search-menu/results.hbs b/app/assets/javascripts/discourse/app/components/search-menu/results.hbs index a026fd5322f..bfbf0911971 100644 --- a/app/assets/javascripts/discourse/app/components/search-menu/results.hbs +++ b/app/assets/javascripts/discourse/app/components/search-menu/results.hbs @@ -43,6 +43,7 @@ @resultTypes={{this.resultTypesWithComponent}} @topicResultsOnly={{true}} @closeSearchMenu={{@closeSearchMenu}} + @searchLogId={{this.searchLogId}} /> <SearchMenu::Results::MoreLink @updateTypeFilter={{@updateTypeFilter}} @@ -63,6 +64,7 @@ @closeSearchMenu={{@closeSearchMenu}} @searchTermChanged={{@searchTermChanged}} @displayNameWithUser={{true}} + @searchLogId={{this.searchLogId}} /> {{/if}} {{/if}} diff --git a/app/assets/javascripts/discourse/app/components/search-menu/results.js b/app/assets/javascripts/discourse/app/components/search-menu/results.js index 3be639b32b4..4c8be480c06 100644 --- a/app/assets/javascripts/discourse/app/components/search-menu/results.js +++ b/app/assets/javascripts/discourse/app/components/search-menu/results.js @@ -46,6 +46,10 @@ export default class Results extends Component { return content; } + get searchLogId() { + return this.search.results.grouped_search_result?.search_log_id; + } + @action updateSearchTopics(value) { this.searchTopics = value; diff --git a/app/assets/javascripts/discourse/app/components/search-menu/results/types.hbs b/app/assets/javascripts/discourse/app/components/search-menu/results/types.hbs index 2c9660a994b..11cf81ebb71 100644 --- a/app/assets/javascripts/discourse/app/components/search-menu/results/types.hbs +++ b/app/assets/javascripts/discourse/app/components/search-menu/results/types.hbs @@ -11,10 +11,19 @@ {{#each resultType.results as |result|}} {{! template-lint-disable no-pointer-down-event-binding }} {{! template-lint-disable no-invalid-interactive }} - <li class="item" {{on "keydown" this.onKeydown}}> + <li + class="item" + {{on + "keydown" + (fn this.onKeydown (hash resultType=resultType result=result)) + }} + > <a href={{or result.url result.path}} - {{on "click" this.onClick}} + {{on + "click" + (fn this.onClick (hash resultType=resultType result=result)) + }} class="search-link" > <resultType.component diff --git a/app/assets/javascripts/discourse/app/components/search-menu/results/types.js b/app/assets/javascripts/discourse/app/components/search-menu/results/types.js index 82a52cf4589..1f4edc87f59 100644 --- a/app/assets/javascripts/discourse/app/components/search-menu/results/types.js +++ b/app/assets/javascripts/discourse/app/components/search-menu/results/types.js @@ -2,6 +2,7 @@ import Component from "@glimmer/component"; import { action } from "@ember/object"; import { service } from "@ember/service"; import { wantsNewWindow } from "discourse/lib/intercept-click"; +import { logSearchLinkClick } from "discourse/lib/search"; import DiscourseURL from "discourse/lib/url"; export default class Types extends Component { @@ -22,7 +23,13 @@ export default class Types extends Component { } @action - onClick(event) { + onClick({ resultType, result }, event) { + logSearchLinkClick({ + searchLogId: this.args.searchLogId, + searchResultId: result.id, + searchResultType: resultType.type, + }); + if (wantsNewWindow(event)) { return; } @@ -32,7 +39,7 @@ export default class Types extends Component { } @action - onKeydown(event) { + onKeydown({ resultType, result }, event) { if (event.key === "Escape") { this.args.closeSearchMenu(); event.preventDefault(); @@ -40,6 +47,11 @@ export default class Types extends Component { } else if (event.key === "Enter") { event.preventDefault(); event.stopPropagation(); + logSearchLinkClick({ + searchLogId: this.args.searchLogId, + searchResultId: result.id, + searchResultType: resultType.type, + }); this.routeToSearchResult(event.target.href); return false; } diff --git a/app/assets/javascripts/discourse/app/widgets/header.js b/app/assets/javascripts/discourse/app/widgets/header.js index 0e688122554..b83f3ae1974 100644 --- a/app/assets/javascripts/discourse/app/widgets/header.js +++ b/app/assets/javascripts/discourse/app/widgets/header.js @@ -7,7 +7,6 @@ import { headerIconsDAG } from "discourse/components/header/icons"; import { addExtraUserClasses } from "discourse/helpers/user-avatar"; import { wantsNewWindow } from "discourse/lib/intercept-click"; import scrollLock from "discourse/lib/scroll-lock"; -import { logSearchLinkClick } from "discourse/lib/search"; import { isDocumentRTL } from "discourse/lib/text-direction"; import DiscourseURL from "discourse/lib/url"; import { scrollTop } from "discourse/mixins/scroll-top"; @@ -602,24 +601,6 @@ export default createWidget("header", { this.toggleBodyScrolling(false); }, - linkClickedEvent(attrs) { - let searchContextEnabled = false; - if (attrs) { - searchContextEnabled = attrs.searchContextEnabled; - - const { searchLogId, searchResultId, searchResultType } = attrs; - if (searchLogId && searchResultId && searchResultType) { - logSearchLinkClick({ searchLogId, searchResultId, searchResultType }); - } - } - - if (!searchContextEnabled) { - this.closeAll(); - } - - this.updateHighlight(); - }, - toggleSearchMenu() { if (this.site.mobileView) { const context = this.search.searchContext; diff --git a/app/assets/javascripts/discourse/tests/acceptance/search-test.js b/app/assets/javascripts/discourse/tests/acceptance/search-test.js index 6ed421bb43e..b53025ab4a1 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/search-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/search-test.js @@ -496,6 +496,10 @@ acceptance("Search - Authenticated", function (needs) { server.get("/t/2179.json", () => { return helper.response({}); }); + + server.post("/search/click", () => { + return helper.response({ success: "OK" }); + }); }); test("full page search - the right filters are shown", async function (assert) { @@ -1140,6 +1144,10 @@ acceptance("Search - assistant", function (needs) { ], }); }); + + server.post("/search/click", () => { + return helper.response({ success: "OK" }); + }); }); test("initial options - shows category shortcuts when typing #", async function (assert) { diff --git a/spec/system/search_spec.rb b/spec/system/search_spec.rb index 623ba33da70..fdd932cc09d 100644 --- a/spec/system/search_spec.rb +++ b/spec/system/search_spec.rb @@ -106,5 +106,25 @@ describe "Search", type: :system do search_page.click_search_icon expect(search_page).to have_topic_title_for_first_search_result(topic.title) end + + it "tracks search result clicks" do + expect(SearchLog.count).to eq(0) + + visit("/") + search_page.click_search_icon + search_page.type_in_search_menu("test") + search_page.click_search_menu_link + + expect(search_page).to have_topic_title_for_first_search_result(topic.title) + find(".search-menu-container .search-result-topic", text: topic.title).click + + try_until_success { expect(SearchLog.count).to eq(1) } + try_until_success { expect(SearchLog.last.search_result_id).not_to eq(nil) } + + log = SearchLog.last + expect(log.term).to eq("test") + expect(log.search_result_id).to eq(topic.first_post.id) + expect(log.search_type).to eq(SearchLog.search_types[:header]) + end end end