FIX: Log search result clicks in header search menu (#26500)

This logic wasn't fully ported to the new search menu implementation.
This commit is contained in:
David Taylor 2024-04-04 14:52:32 +01:00 committed by GitHub
parent c117f6de04
commit 9af957014e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 59 additions and 23 deletions

View File

@ -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}}

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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) {

View File

@ -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