UX: Display only top categories in hamburger menu (#6146)

This commit is contained in:
Vinoth Kannan 2018-07-27 12:11:07 +05:30 committed by GitHub
parent e4208113a8
commit dac29b5ebc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 122 additions and 46 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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("")
);
}
});