mirror of
https://github.com/discourse/discourse.git
synced 2025-03-09 14:34:35 +00:00
FEATURE: new category setting for whether to show latest topics or top topics by default
This commit is contained in:
parent
bcf634ca85
commit
6aab8cb331
@ -21,5 +21,13 @@ export default buildCategoryPanel('settings', {
|
|||||||
{name: I18n.t('category.sort_ascending'), value: 'true'},
|
{name: I18n.t('category.sort_ascending'), value: 'true'},
|
||||||
{name: I18n.t('category.sort_descending'), value: 'false'}
|
{name: I18n.t('category.sort_descending'), value: 'false'}
|
||||||
];
|
];
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed
|
||||||
|
availableViews() {
|
||||||
|
return [
|
||||||
|
{name: I18n.t('filters.latest.title'), value: 'latest'},
|
||||||
|
{name: I18n.t('filters.top.title'), value: 'top'}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -104,7 +104,8 @@ const Category = RestModel.extend({
|
|||||||
sort_ascending: this.get('sort_ascending'),
|
sort_ascending: this.get('sort_ascending'),
|
||||||
topic_featured_link_allowed: this.get('topic_featured_link_allowed'),
|
topic_featured_link_allowed: this.get('topic_featured_link_allowed'),
|
||||||
show_subcategory_list: this.get('show_subcategory_list'),
|
show_subcategory_list: this.get('show_subcategory_list'),
|
||||||
num_featured_topics: this.get('num_featured_topics')
|
num_featured_topics: this.get('num_featured_topics'),
|
||||||
|
default_view: this.get('default_view')
|
||||||
},
|
},
|
||||||
type: id ? 'PUT' : 'POST'
|
type: id ? 'PUT' : 'POST'
|
||||||
});
|
});
|
||||||
|
@ -13,9 +13,9 @@ export default {
|
|||||||
app.DiscoveryCategoryNoneController = DiscoverySortableController.extend();
|
app.DiscoveryCategoryNoneController = DiscoverySortableController.extend();
|
||||||
app.DiscoveryCategoryWithIDController = DiscoverySortableController.extend();
|
app.DiscoveryCategoryWithIDController = DiscoverySortableController.extend();
|
||||||
|
|
||||||
app.DiscoveryCategoryRoute = buildCategoryRoute('latest');
|
app.DiscoveryCategoryRoute = buildCategoryRoute('default');
|
||||||
app.DiscoveryParentCategoryRoute = buildCategoryRoute('latest');
|
app.DiscoveryParentCategoryRoute = buildCategoryRoute('default');
|
||||||
app.DiscoveryCategoryNoneRoute = buildCategoryRoute('latest', {no_subcategories: true});
|
app.DiscoveryCategoryNoneRoute = buildCategoryRoute('default', {no_subcategories: true});
|
||||||
|
|
||||||
const site = Discourse.Site.current();
|
const site = Discourse.Site.current();
|
||||||
site.get('filters').forEach(filter => {
|
site.get('filters').forEach(filter => {
|
||||||
|
@ -6,7 +6,7 @@ import CategoryList from 'discourse/models/category-list';
|
|||||||
import Category from 'discourse/models/category';
|
import Category from 'discourse/models/category';
|
||||||
|
|
||||||
// A helper function to create a category route with parameters
|
// A helper function to create a category route with parameters
|
||||||
export default (filter, params) => {
|
export default (filterArg, params) => {
|
||||||
return Discourse.Route.extend({
|
return Discourse.Route.extend({
|
||||||
queryParams,
|
queryParams,
|
||||||
|
|
||||||
@ -37,9 +37,13 @@ export default (filter, params) => {
|
|||||||
this._retrieveTopicList(model.category, transition)]);
|
this._retrieveTopicList(model.category, transition)]);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
filter(category) {
|
||||||
|
return filterArg === 'default' ? (category.get('default_view') || 'latest') : filterArg;
|
||||||
|
},
|
||||||
|
|
||||||
_setupNavigation(category) {
|
_setupNavigation(category) {
|
||||||
const noSubcategories = params && !!params.no_subcategories,
|
const noSubcategories = params && !!params.no_subcategories,
|
||||||
filterMode = `c/${Discourse.Category.slugFor(category)}${noSubcategories ? "/none" : ""}/l/${filter}`;
|
filterMode = `c/${Discourse.Category.slugFor(category)}${noSubcategories ? "/none" : ""}/l/${this.filter(category)}`;
|
||||||
|
|
||||||
this.controllerFor('navigation/category').setProperties({
|
this.controllerFor('navigation/category').setProperties({
|
||||||
category,
|
category,
|
||||||
@ -60,7 +64,7 @@ export default (filter, params) => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_retrieveTopicList(category, transition) {
|
_retrieveTopicList(category, transition) {
|
||||||
const listFilter = `c/${Discourse.Category.slugFor(category)}/l/${filter}`,
|
const listFilter = `c/${Discourse.Category.slugFor(category)}/l/${this.filter(category)}`,
|
||||||
findOpts = filterQueryParams(transition.queryParams, params),
|
findOpts = filterQueryParams(transition.queryParams, params),
|
||||||
extras = { cached: this.isPoppedState(transition) };
|
extras = { cached: this.isPoppedState(transition) };
|
||||||
|
|
||||||
@ -72,8 +76,8 @@ export default (filter, params) => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
titleToken() {
|
titleToken() {
|
||||||
const filterText = I18n.t('filters.' + filter.replace('/', '.') + '.title'),
|
const category = this.currentModel.category,
|
||||||
category = this.currentModel.category;
|
filterText = I18n.t('filters.' + this.filter(category).replace('/', '.') + '.title');
|
||||||
|
|
||||||
return I18n.t('filters.with_category', { filter: filterText, category: category.get('name') });
|
return I18n.t('filters.with_category', { filter: filterText, category: category.get('name') });
|
||||||
},
|
},
|
||||||
@ -82,7 +86,8 @@ export default (filter, params) => {
|
|||||||
const topics = this.get('topics'),
|
const topics = this.get('topics'),
|
||||||
category = model.category,
|
category = model.category,
|
||||||
canCreateTopic = topics.get('can_create_topic'),
|
canCreateTopic = topics.get('can_create_topic'),
|
||||||
canCreateTopicOnCategory = category.get('permission') === PermissionType.FULL;
|
canCreateTopicOnCategory = category.get('permission') === PermissionType.FULL,
|
||||||
|
filter = this.filter(category);
|
||||||
|
|
||||||
this.controllerFor('navigation/category').setProperties({
|
this.controllerFor('navigation/category').setProperties({
|
||||||
canCreateTopicOnCategory: canCreateTopicOnCategory,
|
canCreateTopicOnCategory: canCreateTopicOnCategory,
|
||||||
|
@ -56,6 +56,13 @@
|
|||||||
</label>
|
</label>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section class="field default-view-field">
|
||||||
|
<label>
|
||||||
|
{{i18n "category.default_view"}}
|
||||||
|
{{combo-box valueAttribute="value" content=availableViews value=category.default_view}}
|
||||||
|
</label>
|
||||||
|
</section>
|
||||||
|
|
||||||
{{#if emailInEnabled}}
|
{{#if emailInEnabled}}
|
||||||
<section class='field'>
|
<section class='field'>
|
||||||
<label>
|
<label>
|
||||||
|
@ -244,6 +244,7 @@ class CategoriesController < ApplicationController
|
|||||||
:topic_featured_link_allowed,
|
:topic_featured_link_allowed,
|
||||||
:show_subcategory_list,
|
:show_subcategory_list,
|
||||||
:num_featured_topics,
|
:num_featured_topics,
|
||||||
|
:default_view,
|
||||||
:custom_fields => [params[:custom_fields].try(:keys)],
|
:custom_fields => [params[:custom_fields].try(:keys)],
|
||||||
:permissions => [*p.try(:keys)],
|
:permissions => [*p.try(:keys)],
|
||||||
:allowed_tags => [],
|
:allowed_tags => [],
|
||||||
|
@ -6,6 +6,7 @@ class ListController < ApplicationController
|
|||||||
skip_before_filter :check_xhr
|
skip_before_filter :check_xhr
|
||||||
|
|
||||||
before_filter :set_category, only: [
|
before_filter :set_category, only: [
|
||||||
|
:category_default,
|
||||||
# filtered topics lists
|
# filtered topics lists
|
||||||
Discourse.filters.map { |f| :"category_#{f}" },
|
Discourse.filters.map { |f| :"category_#{f}" },
|
||||||
Discourse.filters.map { |f| :"category_none_#{f}" },
|
Discourse.filters.map { |f| :"category_none_#{f}" },
|
||||||
@ -29,6 +30,7 @@ class ListController < ApplicationController
|
|||||||
Discourse.anonymous_filters,
|
Discourse.anonymous_filters,
|
||||||
Discourse.anonymous_filters.map { |f| "#{f}_feed" },
|
Discourse.anonymous_filters.map { |f| "#{f}_feed" },
|
||||||
# anonymous categorized filters
|
# anonymous categorized filters
|
||||||
|
:category_default,
|
||||||
Discourse.anonymous_filters.map { |f| :"category_#{f}" },
|
Discourse.anonymous_filters.map { |f| :"category_#{f}" },
|
||||||
Discourse.anonymous_filters.map { |f| :"category_none_#{f}" },
|
Discourse.anonymous_filters.map { |f| :"category_none_#{f}" },
|
||||||
Discourse.anonymous_filters.map { |f| :"parent_category_category_#{f}" },
|
Discourse.anonymous_filters.map { |f| :"parent_category_category_#{f}" },
|
||||||
@ -106,6 +108,14 @@ class ListController < ApplicationController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def category_default
|
||||||
|
if @category.default_view == 'top'
|
||||||
|
top(category: @category.id)
|
||||||
|
else
|
||||||
|
self.send(@category.default_view || 'latest')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def topics_by
|
def topics_by
|
||||||
list_opts = build_topic_list_options
|
list_opts = build_topic_list_options
|
||||||
target_user = fetch_user_from_params({ include_inactive: current_user.try(:staff?) }, [:user_stat, :user_option])
|
target_user = fetch_user_from_params({ include_inactive: current_user.try(:staff?) }, [:user_stat, :user_option])
|
||||||
|
@ -21,7 +21,8 @@ class BasicCategorySerializer < ApplicationSerializer
|
|||||||
:sort_order,
|
:sort_order,
|
||||||
:sort_ascending,
|
:sort_ascending,
|
||||||
:show_subcategory_list,
|
:show_subcategory_list,
|
||||||
:num_featured_topics
|
:num_featured_topics,
|
||||||
|
:default_view
|
||||||
|
|
||||||
has_one :uploaded_logo, embed: :object, serializer: CategoryUploadSerializer
|
has_one :uploaded_logo, embed: :object, serializer: CategoryUploadSerializer
|
||||||
has_one :uploaded_background, embed: :object, serializer: CategoryUploadSerializer
|
has_one :uploaded_background, embed: :object, serializer: CategoryUploadSerializer
|
||||||
|
@ -1974,6 +1974,7 @@ en:
|
|||||||
subcategory_num_featured_topics: "Number of featured topics on parent category's page:"
|
subcategory_num_featured_topics: "Number of featured topics on parent category's page:"
|
||||||
all_topics_wiki: "Make new topics wikis by default."
|
all_topics_wiki: "Make new topics wikis by default."
|
||||||
sort_order: "Default Sort:"
|
sort_order: "Default Sort:"
|
||||||
|
default_view: "Default View:"
|
||||||
allow_badges_label: "Allow badges to be awarded in this category"
|
allow_badges_label: "Allow badges to be awarded in this category"
|
||||||
edit_permissions: "Edit Permissions"
|
edit_permissions: "Edit Permissions"
|
||||||
add_permission: "Add Permission"
|
add_permission: "Add Permission"
|
||||||
|
@ -491,7 +491,7 @@ Discourse::Application.routes.draw do
|
|||||||
get "c/:parent_category_slug/:category_slug/find_by_slug" => "categories#find_by_slug"
|
get "c/:parent_category_slug/:category_slug/find_by_slug" => "categories#find_by_slug"
|
||||||
get "c/:category.rss" => "list#category_feed", format: :rss
|
get "c/:category.rss" => "list#category_feed", format: :rss
|
||||||
get "c/:parent_category/:category.rss" => "list#category_feed", format: :rss
|
get "c/:parent_category/:category.rss" => "list#category_feed", format: :rss
|
||||||
get "c/:category" => "list#category_latest"
|
get "c/:category" => "list#category_default", as: "category_default"
|
||||||
get "c/:category/none" => "list#category_none_latest"
|
get "c/:category/none" => "list#category_none_latest"
|
||||||
get "c/:parent_category/:category/(:id)" => "list#parent_category_category_latest", constraints: { id: /\d+/ }
|
get "c/:parent_category/:category/(:id)" => "list#parent_category_category_latest", constraints: { id: /\d+/ }
|
||||||
get "c/:category/l/top" => "list#category_top", as: "category_top"
|
get "c/:category/l/top" => "list#category_top", as: "category_top"
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
class AddDefaultViewToCategories < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :categories, :default_view, :string, null: true, limit: 50
|
||||||
|
end
|
||||||
|
end
|
@ -141,7 +141,6 @@ describe ListController do
|
|||||||
|
|
||||||
it { is_expected.not_to respond_with(:success) }
|
it { is_expected.not_to respond_with(:success) }
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'feed' do
|
describe 'feed' do
|
||||||
@ -151,6 +150,29 @@ describe ListController do
|
|||||||
expect(response.content_type).to eq('application/rss+xml')
|
expect(response.content_type).to eq('application/rss+xml')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "category default views" do
|
||||||
|
it "top default view" do
|
||||||
|
category.update_attributes!(default_view: 'top')
|
||||||
|
described_class.expects(:best_period_for).returns('yearly')
|
||||||
|
xhr :get, :category_default, category: category.slug
|
||||||
|
expect(response).to be_success
|
||||||
|
end
|
||||||
|
|
||||||
|
it "default view is nil" do
|
||||||
|
category.update_attributes!(default_view: nil)
|
||||||
|
described_class.expects(:best_period_for).never
|
||||||
|
xhr :get, :category_default, category: category.slug
|
||||||
|
expect(response).to be_success
|
||||||
|
end
|
||||||
|
|
||||||
|
it "default view is latest" do
|
||||||
|
category.update_attributes!(default_view: 'latest')
|
||||||
|
described_class.expects(:best_period_for).never
|
||||||
|
xhr :get, :category_default, category: category.slug
|
||||||
|
expect(response).to be_success
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user