diff --git a/app/assets/javascripts/discourse/app/components/user-menu/items-list.hbs b/app/assets/javascripts/discourse/app/components/user-menu/items-list.hbs
index 436bee4b915..e54cd281f62 100644
--- a/app/assets/javascripts/discourse/app/components/user-menu/items-list.hbs
+++ b/app/assets/javascripts/discourse/app/components/user-menu/items-list.hbs
@@ -5,7 +5,7 @@
{{else if this.items.length}}
{{#each this.items as |item|}}
-
+
{{/each}}
diff --git a/app/assets/javascripts/discourse/app/components/user-menu/menu-item.js b/app/assets/javascripts/discourse/app/components/user-menu/menu-item.js
index 62dca80f57f..b055d3bf4aa 100644
--- a/app/assets/javascripts/discourse/app/components/user-menu/menu-item.js
+++ b/app/assets/javascripts/discourse/app/components/user-menu/menu-item.js
@@ -54,7 +54,10 @@ export default class UserMenuItem extends Component {
}
@action
- onClick() {
- return this.#item.onClick();
+ onClick(event) {
+ return this.#item.onClick({
+ event,
+ closeUserMenu: this.args.closeUserMenu,
+ });
}
}
diff --git a/app/assets/javascripts/discourse/app/lib/user-menu/base-item.js b/app/assets/javascripts/discourse/app/lib/user-menu/base-item.js
index 39baad43981..ab5fb90c379 100644
--- a/app/assets/javascripts/discourse/app/lib/user-menu/base-item.js
+++ b/app/assets/javascripts/discourse/app/lib/user-menu/base-item.js
@@ -1,3 +1,5 @@
+import DiscourseURL from "discourse/lib/url";
+
export default class UserMenuBaseItem {
get className() {}
@@ -26,4 +28,13 @@ export default class UserMenuBaseItem {
get descriptionClass() {}
get topicId() {}
+
+ onClick({ event, closeUserMenu }) {
+ closeUserMenu();
+ const href = this.linkHref;
+ if (href) {
+ DiscourseURL.routeTo(href);
+ }
+ event.preventDefault();
+ }
}
diff --git a/app/assets/javascripts/discourse/app/lib/user-menu/notification-item.js b/app/assets/javascripts/discourse/app/lib/user-menu/notification-item.js
index 65717c73925..7660be40396 100644
--- a/app/assets/javascripts/discourse/app/lib/user-menu/notification-item.js
+++ b/app/assets/javascripts/discourse/app/lib/user-menu/notification-item.js
@@ -82,5 +82,6 @@ export default class UserMenuNotificationItem extends UserMenuBaseItem {
setTransientHeader("Discourse-Clear-Notifications", this.notification.id);
cookie("cn", this.notification.id, { path: getURL("/") });
}
+ super.onClick(...arguments);
}
}
diff --git a/app/assets/javascripts/discourse/tests/acceptance/user-menu-test.js b/app/assets/javascripts/discourse/tests/acceptance/user-menu-test.js
index b1f2d88f2d8..e13541f1e1c 100644
--- a/app/assets/javascripts/discourse/tests/acceptance/user-menu-test.js
+++ b/app/assets/javascripts/discourse/tests/acceptance/user-menu-test.js
@@ -1,4 +1,4 @@
-import { click, visit } from "@ember/test-helpers";
+import { click, currentURL, visit } from "@ember/test-helpers";
import {
acceptance,
exists,
@@ -83,6 +83,37 @@ acceptance("User menu", function (needs) {
);
});
+ test("clicking on user menu items", async function (assert) {
+ await visit("/");
+ await click(".d-header-icons .current-user");
+ await click("#user-menu-button-review-queue");
+ await click("#quick-access-review-queue li.reviewable.pending a");
+
+ assert.strictEqual(
+ currentURL(),
+ "/review/17",
+ "clicking on an item results in navigation to the item's page"
+ );
+ assert.notOk(
+ exists(".user-menu"),
+ "clicking on an item closes the menu after navigating"
+ );
+
+ await click(".d-header-icons .current-user");
+ await click("#user-menu-button-review-queue");
+ await click("#quick-access-review-queue li.reviewable.pending a");
+
+ assert.strictEqual(
+ currentURL(),
+ "/review/17",
+ "clicking on the same item again keeps on the same page"
+ );
+ assert.notOk(
+ exists(".user-menu"),
+ "clicking on the same item again closes the menu"
+ );
+ });
+
test("tabs added via the plugin API", async function (assert) {
withPluginApi("0.1", (api) => {
api.registerUserMenuTab((UserMenuTab) => {