diff --git a/app/assets/javascripts/discourse/components/edit-category-settings.js.es6 b/app/assets/javascripts/discourse/components/edit-category-settings.js.es6 index 0d5336835ac..6a97b28ebe7 100644 --- a/app/assets/javascripts/discourse/components/edit-category-settings.js.es6 +++ b/app/assets/javascripts/discourse/components/edit-category-settings.js.es6 @@ -27,6 +27,13 @@ export default buildCategoryPanel('settings', { ]; }, + @computed + availableTopPeriods() { + return ['all', 'yearly', 'quarterly', 'monthly', 'weekly', 'daily'].map((p) => { + return {name: I18n.t(`filters.top.${p}.title`), value: p}; + }); + }, + @computed availableSorts() { return ['likes', 'op_likes', 'views', 'posts', 'activity', 'posters', 'category', 'created'] diff --git a/app/assets/javascripts/discourse/models/category.js.es6 b/app/assets/javascripts/discourse/models/category.js.es6 index 8550159ddd3..16304f453e6 100644 --- a/app/assets/javascripts/discourse/models/category.js.es6 +++ b/app/assets/javascripts/discourse/models/category.js.es6 @@ -106,7 +106,8 @@ const Category = RestModel.extend({ show_subcategory_list: this.get('show_subcategory_list'), num_featured_topics: this.get('num_featured_topics'), default_view: this.get('default_view'), - subcategory_list_style: this.get('subcategory_list_style') + subcategory_list_style: this.get('subcategory_list_style'), + default_top_period: this.get('default_top_period') }, type: id ? 'PUT' : 'POST' }); diff --git a/app/assets/javascripts/discourse/templates/components/edit-category-settings.hbs b/app/assets/javascripts/discourse/templates/components/edit-category-settings.hbs index e12846ea3c0..aae72706cd7 100644 --- a/app/assets/javascripts/discourse/templates/components/edit-category-settings.hbs +++ b/app/assets/javascripts/discourse/templates/components/edit-category-settings.hbs @@ -44,6 +44,13 @@ </label> </section> +<section class="field default-top-period-field"> + <label> + {{i18n "category.default_top_period"}} + {{combo-box valueAttribute="value" content=availableTopPeriods value=category.default_top_period}} + </label> +</section> + <section class="field"> <label> {{i18n "category.sort_order"}} diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb index 71d5e7668ad..b7e85c72fe9 100644 --- a/app/controllers/categories_controller.rb +++ b/app/controllers/categories_controller.rb @@ -249,6 +249,7 @@ class CategoriesController < ApplicationController :num_featured_topics, :default_view, :subcategory_list_style, + :default_top_period, :custom_fields => [params[:custom_fields].try(:keys)], :permissions => [*p.try(:keys)], :allowed_tags => [], diff --git a/app/controllers/list_controller.rb b/app/controllers/list_controller.rb index 91eeeab5b29..69391459d86 100644 --- a/app/controllers/list_controller.rb +++ b/app/controllers/list_controller.rb @@ -366,8 +366,15 @@ class ListController < ApplicationController exclude_category_ids.pluck(:id) end - def self.best_period_with_topics_for(previous_visit_at, category_id=nil) - best_periods_for(previous_visit_at).each do |period| + def self.best_period_for(previous_visit_at, category_id=nil) + default_period = ((category_id && Category.where(id: category_id).pluck(:default_top_period).first) || + SiteSetting.top_page_default_timeframe).to_sym + + best_period_with_topics_for(previous_visit_at, category_id, default_period) || default_period + end + + def self.best_period_with_topics_for(previous_visit_at, category_id=nil, default_period=SiteSetting.top_page_default_timeframe) + best_periods_for(previous_visit_at, default_period.to_sym).each do |period| top_topics = TopTopic.where("#{period}_score > 0") top_topics = top_topics.joins(:topic).where("topics.category_id = ?", category_id) if category_id top_topics = top_topics.limit(SiteSetting.topics_per_period_in_top_page) @@ -377,14 +384,8 @@ class ListController < ApplicationController false end - def self.best_period_for(previous_visit_at, category_id=nil) - best_period_with_topics_for(previous_visit_at, category_id) || - SiteSetting.top_page_default_timeframe.to_sym - end - - def self.best_periods_for(date) + def self.best_periods_for(date, default_period=:all) date ||= 1.year.ago - default_period = SiteSetting.top_page_default_timeframe.to_sym periods = [] periods << default_period if :all != default_period periods << :daily if :daily != default_period && date > 8.days.ago diff --git a/app/models/category.rb b/app/models/category.rb index 7d0d2ef199e..120ba3de299 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -561,6 +561,7 @@ end # num_featured_topics :integer default(3) # default_view :string(50) # subcategory_list_style :string(50) default("rows_with_featured_topics") +# default_top_period :string(20) default("all") # # Indexes # diff --git a/app/serializers/basic_category_serializer.rb b/app/serializers/basic_category_serializer.rb index c96fb58b199..01a088976ee 100644 --- a/app/serializers/basic_category_serializer.rb +++ b/app/serializers/basic_category_serializer.rb @@ -23,7 +23,8 @@ class BasicCategorySerializer < ApplicationSerializer :show_subcategory_list, :num_featured_topics, :default_view, - :subcategory_list_style + :subcategory_list_style, + :default_top_period has_one :uploaded_logo, embed: :object, serializer: CategoryUploadSerializer has_one :uploaded_background, embed: :object, serializer: CategoryUploadSerializer diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index cd3f3d15b13..85ad37d3452 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -1993,6 +1993,7 @@ en: subcategory_list_style: "Subcategory List Style:" sort_order: "Topic List Sort By:" default_view: "Default Topic List:" + default_top_period: "Default Top Period:" allow_badges_label: "Allow badges to be awarded in this category" edit_permissions: "Edit Permissions" add_permission: "Add Permission" diff --git a/db/migrate/20170322191305_add_default_top_period_to_categories.rb b/db/migrate/20170322191305_add_default_top_period_to_categories.rb new file mode 100644 index 00000000000..e6322cbdf8e --- /dev/null +++ b/db/migrate/20170322191305_add_default_top_period_to_categories.rb @@ -0,0 +1,5 @@ +class AddDefaultTopPeriodToCategories < ActiveRecord::Migration + def change + add_column :categories, :default_top_period, :string, limit: 20, default: 'all' + end +end diff --git a/spec/controllers/list_controller_spec.rb b/spec/controllers/list_controller_spec.rb index 5a4a94d800e..9673858aaa3 100644 --- a/spec/controllers/list_controller_spec.rb +++ b/spec/controllers/list_controller_spec.rb @@ -193,8 +193,8 @@ describe ListController do describe "category default views" do it "top default view" do - category.update_attributes!(default_view: 'top') - described_class.expects(:best_period_for).returns('yearly') + category.update_attributes!(default_view: 'top', default_top_period: 'monthly') + described_class.expects(:best_period_with_topics_for).with(anything, category.id, :monthly).returns(:monthly) xhr :get, :category_default, category: category.slug expect(response).to be_success end @@ -291,62 +291,52 @@ describe ListController do describe "best_periods_for" do it "returns yearly for more than 180 days" do - SiteSetting.top_page_default_timeframe = 'all' - expect(ListController.best_periods_for(nil)).to eq([:yearly]) - expect(ListController.best_periods_for(180.days.ago)).to eq([:yearly]) + expect(ListController.best_periods_for(nil, :all)).to eq([:yearly]) + expect(ListController.best_periods_for(180.days.ago, :all)).to eq([:yearly]) end it "includes monthly when less than 180 days and more than 35 days" do - SiteSetting.top_page_default_timeframe = 'all' (35...180).each do |date| - expect(ListController.best_periods_for(date.days.ago)).to eq([:monthly, :yearly]) + expect(ListController.best_periods_for(date.days.ago, :all)).to eq([:monthly, :yearly]) end end it "includes weekly when less than 35 days and more than 8 days" do - SiteSetting.top_page_default_timeframe = 'all' (8...35).each do |date| - expect(ListController.best_periods_for(date.days.ago)).to eq([:weekly, :monthly, :yearly]) + expect(ListController.best_periods_for(date.days.ago, :all)).to eq([:weekly, :monthly, :yearly]) end end it "includes daily when less than 8 days" do - SiteSetting.top_page_default_timeframe = 'all' (0...8).each do |date| - expect(ListController.best_periods_for(date.days.ago)).to eq([:daily, :weekly, :monthly, :yearly]) + expect(ListController.best_periods_for(date.days.ago, :all)).to eq([:daily, :weekly, :monthly, :yearly]) end end it "returns default even for more than 180 days" do - SiteSetting.top_page_default_timeframe = 'monthly' - expect(ListController.best_periods_for(nil)).to eq([:monthly, :yearly]) - expect(ListController.best_periods_for(180.days.ago)).to eq([:monthly, :yearly]) + expect(ListController.best_periods_for(nil, :monthly)).to eq([:monthly, :yearly]) + expect(ListController.best_periods_for(180.days.ago, :monthly)).to eq([:monthly, :yearly]) end it "returns default even when less than 180 days and more than 35 days" do - SiteSetting.top_page_default_timeframe = 'weekly' (35...180).each do |date| - expect(ListController.best_periods_for(date.days.ago)).to eq([:weekly, :monthly, :yearly]) + expect(ListController.best_periods_for(date.days.ago, :weekly)).to eq([:weekly, :monthly, :yearly]) end end it "returns default even when less than 35 days and more than 8 days" do - SiteSetting.top_page_default_timeframe = 'daily' (8...35).each do |date| - expect(ListController.best_periods_for(date.days.ago)).to eq([:daily, :weekly, :monthly, :yearly]) + expect(ListController.best_periods_for(date.days.ago, :daily)).to eq([:daily, :weekly, :monthly, :yearly]) end end it "doesn't return default when set to all" do - SiteSetting.top_page_default_timeframe = 'all' - expect(ListController.best_periods_for(nil)).to eq([:yearly]) + expect(ListController.best_periods_for(nil, :all)).to eq([:yearly]) end it "doesn't return value twice when matches default" do - SiteSetting.top_page_default_timeframe = 'yearly' - expect(ListController.best_periods_for(nil)).to eq([:yearly]) + expect(ListController.best_periods_for(nil, :yearly)).to eq([:yearly]) end - end describe "categories suppression" do