mirror of
https://github.com/discourse/discourse.git
synced 2025-02-20 18:58:10 +00:00
UX: Display only top categories in hamburger menu (#6146)
This commit is contained in:
parent
e4208113a8
commit
dac29b5ebc
@ -51,7 +51,7 @@ export default createWidget("hamburger-categories", {
|
||||
|
||||
html(attrs) {
|
||||
const href = Discourse.getURL("/categories");
|
||||
const result = [
|
||||
let result = [
|
||||
h(
|
||||
"li.heading",
|
||||
h(
|
||||
@ -66,8 +66,23 @@ export default createWidget("hamburger-categories", {
|
||||
if (categories.length === 0) {
|
||||
return;
|
||||
}
|
||||
return result.concat(
|
||||
result = result.concat(
|
||||
categories.map(c => this.attach("hamburger-category", c))
|
||||
);
|
||||
|
||||
if (attrs.showMore) {
|
||||
result = result.concat(
|
||||
h(
|
||||
"li.footer",
|
||||
h(
|
||||
"a.d-link.more-link",
|
||||
{ attributes: { href } },
|
||||
I18n.t("categories.more")
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
@ -176,20 +176,29 @@ export default createWidget("hamburger-menu", {
|
||||
},
|
||||
|
||||
listCategories() {
|
||||
const hideUncategorized = !this.siteSettings.allow_uncategorized_topics;
|
||||
const isStaff = Discourse.User.currentProp("staff");
|
||||
const maxCategoriesToDisplay = 6;
|
||||
const categoriesList = this.site
|
||||
.get("categoriesByCount")
|
||||
.reject(c => c.parent_category_id);
|
||||
let categories = [];
|
||||
let showMore = categoriesList.length > maxCategoriesToDisplay;
|
||||
|
||||
const categories = this.site.get("categoriesList").reject(c => {
|
||||
if (c.get("parentCategory.show_subcategory_list")) {
|
||||
return true;
|
||||
}
|
||||
if (hideUncategorized && c.get("isUncategorizedCategory") && !isStaff) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (this.currentUser) {
|
||||
let categoryIds = this.currentUser.get("top_category_ids") || [];
|
||||
categoryIds = categoryIds.concat(categoriesList.map(c => c.id)).uniq();
|
||||
|
||||
return this.attach("hamburger-categories", { categories });
|
||||
showMore = categoryIds.length > maxCategoriesToDisplay;
|
||||
categoryIds = categoryIds.slice(0, maxCategoriesToDisplay);
|
||||
|
||||
categories = categoryIds.map(id => {
|
||||
return categoriesList.find(c => c.id === id);
|
||||
});
|
||||
} else {
|
||||
showMore = categoriesList.length > maxCategoriesToDisplay;
|
||||
categories = categoriesList.slice(0, maxCategoriesToDisplay);
|
||||
}
|
||||
|
||||
return this.attach("hamburger-categories", { categories, showMore });
|
||||
},
|
||||
|
||||
footerLinks(prioritizeFaq, faqUrl) {
|
||||
|
@ -108,6 +108,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
.category-links {
|
||||
.footer {
|
||||
clear: both;
|
||||
display: block;
|
||||
text-align: right;
|
||||
padding-right: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
// note these topic counts only appear for anons in the category hamburger drop down
|
||||
b.topics-count {
|
||||
color: dark-light-choose($primary-medium, $secondary-medium);
|
||||
|
@ -2,6 +2,8 @@ require_dependency 'new_post_manager'
|
||||
|
||||
class CurrentUserSerializer < BasicUserSerializer
|
||||
|
||||
MAX_TOP_CATEGORIES_COUNT = 6.freeze
|
||||
|
||||
attributes :name,
|
||||
:unread_notifications,
|
||||
:unread_private_messages,
|
||||
@ -41,7 +43,8 @@ class CurrentUserSerializer < BasicUserSerializer
|
||||
:primary_group_name,
|
||||
:can_create_topic,
|
||||
:link_posting_access,
|
||||
:external_id
|
||||
:external_id,
|
||||
:top_category_ids
|
||||
|
||||
def link_posting_access
|
||||
scope.link_posting_access
|
||||
@ -153,9 +156,20 @@ class CurrentUserSerializer < BasicUserSerializer
|
||||
end
|
||||
|
||||
def muted_category_ids
|
||||
@muted_category_ids ||= CategoryUser.where(user_id: object.id,
|
||||
notification_level: TopicUser.notification_levels[:muted])
|
||||
CategoryUser.lookup(object, :muted).pluck(:category_id)
|
||||
end
|
||||
|
||||
def top_category_ids
|
||||
CategoryUser.where(user_id: object.id)
|
||||
.where.not(notification_level: CategoryUser.notification_levels[:muted])
|
||||
.order("
|
||||
CASE
|
||||
WHEN notification_level = 3 THEN 1
|
||||
WHEN notification_level = 2 THEN 2
|
||||
WHEN notification_level = 4 THEN 3
|
||||
END")
|
||||
.pluck(:category_id)
|
||||
.slice(0, MAX_TOP_CATEGORIES_COUNT)
|
||||
end
|
||||
|
||||
def dismissed_banner_key
|
||||
|
@ -571,6 +571,7 @@ en:
|
||||
topic_stat_sentence:
|
||||
one: "%{count} new topic in the past %{unit}."
|
||||
other: "%{count} new topics in the past %{unit}."
|
||||
more: "more"
|
||||
|
||||
ip_lookup:
|
||||
title: IP Address Lookup
|
||||
|
@ -32,4 +32,31 @@ RSpec.describe CurrentUserSerializer do
|
||||
expect(payload[:external_id]).to eq("12345")
|
||||
end
|
||||
end
|
||||
|
||||
context "#top_category_ids" do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:category1) { Fabricate(:category) }
|
||||
let(:category2) { Fabricate(:category) }
|
||||
let :serializer do
|
||||
CurrentUserSerializer.new(user, scope: Guardian.new, root: false)
|
||||
end
|
||||
|
||||
it "should include empty top_category_ids array" do
|
||||
payload = serializer.as_json
|
||||
expect(payload[:top_category_ids]).to eq([])
|
||||
end
|
||||
|
||||
it "should include correct id in top_category_ids array" do
|
||||
category = Category.first
|
||||
CategoryUser.create!(user_id: user.id,
|
||||
category_id: category1.id,
|
||||
notification_level: CategoryUser.notification_levels[:tracking])
|
||||
|
||||
CategoryUser.create!(user_id: user.id,
|
||||
category_id: category2.id,
|
||||
notification_level: CategoryUser.notification_levels[:watching])
|
||||
payload = serializer.as_json
|
||||
expect(payload[:top_category_ids]).to eq([category2.id, category1.id])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -2,6 +2,9 @@ import { moduleForWidget, widgetTest } from "helpers/widget-test";
|
||||
|
||||
moduleForWidget("hamburger-menu");
|
||||
|
||||
const maxCategoriesToDisplay = 6;
|
||||
const topCategoryIds = [2, 3, 1];
|
||||
|
||||
widgetTest("prioritize faq", {
|
||||
template: '{{mount-widget widget="hamburger-menu"}}',
|
||||
|
||||
@ -125,42 +128,40 @@ widgetTest("general links", {
|
||||
}
|
||||
});
|
||||
|
||||
widgetTest("category links", {
|
||||
widgetTest("top categories - anonymous", {
|
||||
template: '{{mount-widget widget="hamburger-menu"}}',
|
||||
anonymous: true,
|
||||
|
||||
test(assert) {
|
||||
const count = this.site.get("categoriesByCount").length;
|
||||
const maximum =
|
||||
count <= maxCategoriesToDisplay ? count : maxCategoriesToDisplay;
|
||||
assert.equal(find(".category-link").length, maximum);
|
||||
}
|
||||
});
|
||||
|
||||
widgetTest("top categories", {
|
||||
template: '{{mount-widget widget="hamburger-menu"}}',
|
||||
|
||||
beforeEach() {
|
||||
const cat = this.site.get("categoriesList")[0];
|
||||
|
||||
const parent = Discourse.Category.create({
|
||||
id: 1,
|
||||
topic_count: 5,
|
||||
name: "parent",
|
||||
url: "https://test.com/parent",
|
||||
show_subcategory_list: true,
|
||||
topicTrackingState: cat.get("topicTrackingState")
|
||||
});
|
||||
const child = Discourse.Category.create({
|
||||
id: 2,
|
||||
parent_category_id: 1,
|
||||
parentCategory: parent,
|
||||
topic_count: 4,
|
||||
name: "child",
|
||||
url: "https://test.com/child",
|
||||
topicTrackingState: cat.get("topicTrackingState")
|
||||
});
|
||||
|
||||
parent.subcategories = [child];
|
||||
|
||||
const list = [parent, child];
|
||||
this.site.set("categoriesList", list);
|
||||
this.currentUser.set("top_category_ids", topCategoryIds);
|
||||
},
|
||||
|
||||
test(assert) {
|
||||
// if show_subcategory_list is enabled we suppress the categories from hamburger
|
||||
// this means that people can be confused about counts
|
||||
assert.equal(this.$(".category-link").length, 1);
|
||||
assert.equal(this.$(".category-link .topics-count").text(), "9");
|
||||
assert.equal(find(".category-link").length, maxCategoriesToDisplay);
|
||||
|
||||
const categoriesList = this.site
|
||||
.get("categoriesByCount")
|
||||
.reject(c => c.parent_category_id);
|
||||
let ids = topCategoryIds
|
||||
.concat(categoriesList.map(c => c.id))
|
||||
.uniq()
|
||||
.slice(0, maxCategoriesToDisplay);
|
||||
|
||||
assert.equal(
|
||||
find(".category-link .category-name").text(),
|
||||
ids.map(i => categoriesList.find(c => c.id === i).name).join("")
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user