mirror of
https://github.com/discourse/discourse.git
synced 2024-12-01 18:05:06 +08:00
FIX: Build correct topic list filter (#11473)
* FIX: 'false' value was treated as a truthy value For example, latest.json?no_subcategories=false used to have set no_subcategories to the string value of 'false', which is not false. * DEV: Remove dead code * FIX: Redirect to /none under the right conditions These conditions are: - neither /all or /none present - only for default filter * FIX: Build correct topic list filter /none was never added to the topic list filter * FIX: Do not show count for subcategories if 'none' category * FIX: preload_key must contain /none if no_subcategories
This commit is contained in:
parent
36b4712349
commit
df26d2e72a
|
@ -75,12 +75,13 @@ const NavItem = EmberObject.extend({
|
||||||
"name",
|
"name",
|
||||||
"category",
|
"category",
|
||||||
"tagId",
|
"tagId",
|
||||||
|
"noSubcategories",
|
||||||
"topicTrackingState.messageCount"
|
"topicTrackingState.messageCount"
|
||||||
)
|
)
|
||||||
count(name, category, tagId) {
|
count(name, category, tagId, noSubcategories) {
|
||||||
const state = this.topicTrackingState;
|
const state = this.topicTrackingState;
|
||||||
if (state) {
|
if (state) {
|
||||||
return state.lookupCount(name, category, tagId);
|
return state.lookupCount(name, category, tagId, noSubcategories);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -466,8 +466,10 @@ const TopicTrackingState = EmberObject.extend({
|
||||||
return new Set(result);
|
return new Set(result);
|
||||||
},
|
},
|
||||||
|
|
||||||
countCategoryByState(type, categoryId, tagId) {
|
countCategoryByState(type, categoryId, tagId, noSubcategories) {
|
||||||
const subcategoryIds = this.getSubCategoryIds(categoryId);
|
const subcategoryIds = noSubcategories
|
||||||
|
? new Set()
|
||||||
|
: this.getSubCategoryIds(categoryId);
|
||||||
const mutedCategoryIds =
|
const mutedCategoryIds =
|
||||||
this.currentUser && this.currentUser.muted_category_ids;
|
this.currentUser && this.currentUser.muted_category_ids;
|
||||||
let filter = type === "new" ? isNew : isUnread;
|
let filter = type === "new" ? isNew : isUnread;
|
||||||
|
@ -485,12 +487,17 @@ const TopicTrackingState = EmberObject.extend({
|
||||||
).length;
|
).length;
|
||||||
},
|
},
|
||||||
|
|
||||||
countNew(categoryId, tagId) {
|
countNew(categoryId, tagId, noSubcategories) {
|
||||||
return this.countCategoryByState("new", categoryId, tagId);
|
return this.countCategoryByState("new", categoryId, tagId, noSubcategories);
|
||||||
},
|
},
|
||||||
|
|
||||||
countUnread(categoryId, tagId) {
|
countUnread(categoryId, tagId, noSubcategories) {
|
||||||
return this.countCategoryByState("unread", categoryId, tagId);
|
return this.countCategoryByState(
|
||||||
|
"unread",
|
||||||
|
categoryId,
|
||||||
|
tagId,
|
||||||
|
noSubcategories
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
forEachTracked(fn) {
|
forEachTracked(fn) {
|
||||||
|
@ -548,20 +555,20 @@ const TopicTrackingState = EmberObject.extend({
|
||||||
return sum;
|
return sum;
|
||||||
},
|
},
|
||||||
|
|
||||||
lookupCount(name, category, tagId) {
|
lookupCount(name, category, tagId, noSubcategories) {
|
||||||
if (name === "latest") {
|
if (name === "latest") {
|
||||||
return (
|
return (
|
||||||
this.lookupCount("new", category, tagId) +
|
this.lookupCount("new", category, tagId, noSubcategories) +
|
||||||
this.lookupCount("unread", category, tagId)
|
this.lookupCount("unread", category, tagId, noSubcategories)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let categoryId = category ? get(category, "id") : null;
|
let categoryId = category ? get(category, "id") : null;
|
||||||
|
|
||||||
if (name === "new") {
|
if (name === "new") {
|
||||||
return this.countNew(categoryId, tagId);
|
return this.countNew(categoryId, tagId, noSubcategories);
|
||||||
} else if (name === "unread") {
|
} else if (name === "unread") {
|
||||||
return this.countUnread(categoryId, tagId);
|
return this.countUnread(categoryId, tagId, noSubcategories);
|
||||||
} else {
|
} else {
|
||||||
const categoryName = name.split("/")[1];
|
const categoryName = name.split("/")[1];
|
||||||
if (categoryName) {
|
if (categoryName) {
|
||||||
|
|
|
@ -20,42 +20,7 @@ export default (filterArg, params) => {
|
||||||
return DiscourseRoute.extend({
|
return DiscourseRoute.extend({
|
||||||
queryParams,
|
queryParams,
|
||||||
|
|
||||||
serialize(modelParams) {
|
|
||||||
if (!modelParams.category_slug_path_with_id) {
|
|
||||||
if (modelParams.id === "none") {
|
|
||||||
const category_slug_path_with_id = [
|
|
||||||
modelParams.parentSlug,
|
|
||||||
modelParams.slug,
|
|
||||||
].join("/");
|
|
||||||
const category = Category.findBySlugPathWithID(
|
|
||||||
category_slug_path_with_id
|
|
||||||
);
|
|
||||||
this.replaceWith("discovery.categoryNone", {
|
|
||||||
category,
|
|
||||||
category_slug_path_with_id,
|
|
||||||
});
|
|
||||||
} else if (modelParams.id === "all") {
|
|
||||||
modelParams.category_slug_path_with_id = [
|
|
||||||
modelParams.parentSlug,
|
|
||||||
modelParams.slug,
|
|
||||||
].join("/");
|
|
||||||
} else {
|
|
||||||
modelParams.category_slug_path_with_id = [
|
|
||||||
modelParams.parentSlug,
|
|
||||||
modelParams.slug,
|
|
||||||
modelParams.id,
|
|
||||||
]
|
|
||||||
.filter((x) => x)
|
|
||||||
.join("/");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return modelParams;
|
|
||||||
},
|
|
||||||
|
|
||||||
model(modelParams) {
|
model(modelParams) {
|
||||||
modelParams = this.serialize(modelParams);
|
|
||||||
|
|
||||||
const category = Category.findBySlugPathWithID(
|
const category = Category.findBySlugPathWithID(
|
||||||
modelParams.category_slug_path_with_id
|
modelParams.category_slug_path_with_id
|
||||||
);
|
);
|
||||||
|
@ -88,12 +53,11 @@ export default (filterArg, params) => {
|
||||||
const { category, modelParams } = model;
|
const { category, modelParams } = model;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
(!params || params.no_subcategories === undefined) &&
|
||||||
category.default_list_filter === "none" &&
|
category.default_list_filter === "none" &&
|
||||||
filterArg === "default" &&
|
filterArg === "default"
|
||||||
modelParams &&
|
|
||||||
modelParams.id !== "all"
|
|
||||||
) {
|
) {
|
||||||
this.replaceWith("discovery.categoryNone", {
|
return this.replaceWith("discovery.categoryNone", {
|
||||||
category,
|
category,
|
||||||
category_slug_path_with_id: modelParams.category_slug_path_with_id,
|
category_slug_path_with_id: modelParams.category_slug_path_with_id,
|
||||||
});
|
});
|
||||||
|
@ -137,11 +101,14 @@ export default (filterArg, params) => {
|
||||||
},
|
},
|
||||||
|
|
||||||
_retrieveTopicList(category, transition, modelParams) {
|
_retrieveTopicList(category, transition, modelParams) {
|
||||||
const listFilter = `c/${Category.slugFor(category)}/${
|
const findOpts = filterQueryParams(modelParams, params);
|
||||||
category.id
|
const extras = { cached: this.isPoppedState(transition) };
|
||||||
}/l/${this.filter(category)}`,
|
|
||||||
findOpts = filterQueryParams(modelParams, params),
|
let listFilter = `c/${Category.slugFor(category)}/${category.id}`;
|
||||||
extras = { cached: this.isPoppedState(transition) };
|
if (findOpts.no_subcategories) {
|
||||||
|
listFilter += "/none";
|
||||||
|
}
|
||||||
|
listFilter += `/l/${this.filter(category)}`;
|
||||||
|
|
||||||
return findTopicList(
|
return findTopicList(
|
||||||
this.store,
|
this.store,
|
||||||
|
|
|
@ -64,7 +64,11 @@ class TopicList < DraftableList
|
||||||
|
|
||||||
def preload_key
|
def preload_key
|
||||||
if @category
|
if @category
|
||||||
|
if @opts[:no_subcategories]
|
||||||
|
"topic_list_#{@category.url.sub(/^\//, '')}/none/l/#{@filter}"
|
||||||
|
else
|
||||||
"topic_list_#{@category.url.sub(/^\//, '')}/l/#{@filter}"
|
"topic_list_#{@category.url.sub(/^\//, '')}/l/#{@filter}"
|
||||||
|
end
|
||||||
else
|
else
|
||||||
"topic_list_#{@filter}"
|
"topic_list_#{@filter}"
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,9 +16,7 @@ module TopicQueryParams
|
||||||
|
|
||||||
# hacky columns get special handling
|
# hacky columns get special handling
|
||||||
options[:topic_ids] = param_to_integer_list(:topic_ids)
|
options[:topic_ids] = param_to_integer_list(:topic_ids)
|
||||||
if options[:no_subcategories] == 'true'
|
options[:no_subcategories] = options[:no_subcategories] == 'true' if options[:no_subcategories].present?
|
||||||
options[:no_subcategories] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
options
|
options
|
||||||
end
|
end
|
||||||
|
|
|
@ -90,4 +90,18 @@ describe TopicList do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "#preload_key" do
|
||||||
|
let(:category) { Fabricate(:category) }
|
||||||
|
|
||||||
|
it "generates correct key for categories" do
|
||||||
|
topic_list = TopicList.new('latest', nil, nil, category: category, category_id: category.id)
|
||||||
|
expect(topic_list.preload_key).to eq("topic_list_c/#{category.slug}/#{category.id}/l/latest")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "generates correct key for 'no subcategories' option" do
|
||||||
|
topic_list = TopicList.new('latest', nil, nil, category: category, category_id: category.id, no_subcategories: true)
|
||||||
|
expect(topic_list.preload_key).to eq("topic_list_c/#{category.slug}/#{category.id}/none/l/latest")
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -88,6 +88,9 @@ RSpec.describe ListController do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "categories and X" do
|
describe "categories and X" do
|
||||||
|
let(:category) { Fabricate(:category_with_definition) }
|
||||||
|
let(:sub_category) { Fabricate(:category_with_definition, parent_category: category) }
|
||||||
|
|
||||||
it "returns top topics" do
|
it "returns top topics" do
|
||||||
Fabricate(:topic, like_count: 1000, posts_count: 100)
|
Fabricate(:topic, like_count: 1000, posts_count: 100)
|
||||||
TopTopic.refresh!
|
TopTopic.refresh!
|
||||||
|
@ -100,6 +103,12 @@ RSpec.describe ListController do
|
||||||
data = response.parsed_body
|
data = response.parsed_body
|
||||||
expect(data["topic_list"]["topics"].length).to eq(2)
|
expect(data["topic_list"]["topics"].length).to eq(2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "returns topics from subcategories when no_subcategories=false" do
|
||||||
|
Fabricate(:topic, category: sub_category)
|
||||||
|
get "/c/#{category.slug}/#{category.id}/l/latest.json?no_subcategories=false"
|
||||||
|
expect(response.parsed_body["topic_list"]["topics"].length).to eq(2)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'titles for crawler layout' do
|
describe 'titles for crawler layout' do
|
||||||
|
|
Loading…
Reference in New Issue
Block a user