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}} @resultTypes={{this.resultTypesWithComponent}}
@topicResultsOnly={{true}} @topicResultsOnly={{true}}
@closeSearchMenu={{@closeSearchMenu}} @closeSearchMenu={{@closeSearchMenu}}
@searchLogId={{this.searchLogId}}
/> />
<SearchMenu::Results::MoreLink <SearchMenu::Results::MoreLink
@updateTypeFilter={{@updateTypeFilter}} @updateTypeFilter={{@updateTypeFilter}}
@ -63,6 +64,7 @@
@closeSearchMenu={{@closeSearchMenu}} @closeSearchMenu={{@closeSearchMenu}}
@searchTermChanged={{@searchTermChanged}} @searchTermChanged={{@searchTermChanged}}
@displayNameWithUser={{true}} @displayNameWithUser={{true}}
@searchLogId={{this.searchLogId}}
/> />
{{/if}} {{/if}}
{{/if}} {{/if}}

View File

@ -46,6 +46,10 @@ export default class Results extends Component {
return content; return content;
} }
get searchLogId() {
return this.search.results.grouped_search_result?.search_log_id;
}
@action @action
updateSearchTopics(value) { updateSearchTopics(value) {
this.searchTopics = value; this.searchTopics = value;

View File

@ -11,10 +11,19 @@
{{#each resultType.results as |result|}} {{#each resultType.results as |result|}}
{{! template-lint-disable no-pointer-down-event-binding }} {{! template-lint-disable no-pointer-down-event-binding }}
{{! template-lint-disable no-invalid-interactive }} {{! 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 <a
href={{or result.url result.path}} href={{or result.url result.path}}
{{on "click" this.onClick}} {{on
"click"
(fn this.onClick (hash resultType=resultType result=result))
}}
class="search-link" class="search-link"
> >
<resultType.component <resultType.component

View File

@ -2,6 +2,7 @@ import Component from "@glimmer/component";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { service } from "@ember/service"; import { service } from "@ember/service";
import { wantsNewWindow } from "discourse/lib/intercept-click"; import { wantsNewWindow } from "discourse/lib/intercept-click";
import { logSearchLinkClick } from "discourse/lib/search";
import DiscourseURL from "discourse/lib/url"; import DiscourseURL from "discourse/lib/url";
export default class Types extends Component { export default class Types extends Component {
@ -22,7 +23,13 @@ export default class Types extends Component {
} }
@action @action
onClick(event) { onClick({ resultType, result }, event) {
logSearchLinkClick({
searchLogId: this.args.searchLogId,
searchResultId: result.id,
searchResultType: resultType.type,
});
if (wantsNewWindow(event)) { if (wantsNewWindow(event)) {
return; return;
} }
@ -32,7 +39,7 @@ export default class Types extends Component {
} }
@action @action
onKeydown(event) { onKeydown({ resultType, result }, event) {
if (event.key === "Escape") { if (event.key === "Escape") {
this.args.closeSearchMenu(); this.args.closeSearchMenu();
event.preventDefault(); event.preventDefault();
@ -40,6 +47,11 @@ export default class Types extends Component {
} else if (event.key === "Enter") { } else if (event.key === "Enter") {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
logSearchLinkClick({
searchLogId: this.args.searchLogId,
searchResultId: result.id,
searchResultType: resultType.type,
});
this.routeToSearchResult(event.target.href); this.routeToSearchResult(event.target.href);
return false; return false;
} }

View File

@ -7,7 +7,6 @@ import { headerIconsDAG } from "discourse/components/header/icons";
import { addExtraUserClasses } from "discourse/helpers/user-avatar"; import { addExtraUserClasses } from "discourse/helpers/user-avatar";
import { wantsNewWindow } from "discourse/lib/intercept-click"; import { wantsNewWindow } from "discourse/lib/intercept-click";
import scrollLock from "discourse/lib/scroll-lock"; import scrollLock from "discourse/lib/scroll-lock";
import { logSearchLinkClick } from "discourse/lib/search";
import { isDocumentRTL } from "discourse/lib/text-direction"; import { isDocumentRTL } from "discourse/lib/text-direction";
import DiscourseURL from "discourse/lib/url"; import DiscourseURL from "discourse/lib/url";
import { scrollTop } from "discourse/mixins/scroll-top"; import { scrollTop } from "discourse/mixins/scroll-top";
@ -602,24 +601,6 @@ export default createWidget("header", {
this.toggleBodyScrolling(false); 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() { toggleSearchMenu() {
if (this.site.mobileView) { if (this.site.mobileView) {
const context = this.search.searchContext; const context = this.search.searchContext;

View File

@ -496,6 +496,10 @@ acceptance("Search - Authenticated", function (needs) {
server.get("/t/2179.json", () => { server.get("/t/2179.json", () => {
return helper.response({}); return helper.response({});
}); });
server.post("/search/click", () => {
return helper.response({ success: "OK" });
});
}); });
test("full page search - the right filters are shown", async function (assert) { 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) { 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 search_page.click_search_icon
expect(search_page).to have_topic_title_for_first_search_result(topic.title) expect(search_page).to have_topic_title_for_first_search_result(topic.title)
end 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
end end