Enable column sorting main topic list

This commit is contained in:
Robin Ward 2013-11-14 15:50:36 -05:00
parent 67041d1c6d
commit 968c0672ef
10 changed files with 78 additions and 50 deletions

View File

@ -46,14 +46,14 @@ Discourse.ListController = Discourse.Controller.extend({
@returns {Ember.Deferred} the promise that will resolve to the list of items. @returns {Ember.Deferred} the promise that will resolve to the list of items.
**/ **/
load: function(filterMode) { load: function(filterMode) {
var listController = this; var self = this;
this.set('loading', true); this.set('loading', true);
var trackingState = Discourse.TopicTrackingState.current(); var trackingState = Discourse.TopicTrackingState.current();
if (filterMode === 'categories') { if (filterMode === 'categories') {
return Discourse.CategoryList.list(filterMode).then(function(items) { return Discourse.CategoryList.list(filterMode).then(function(items) {
listController.setProperties({ self.setProperties({
loading: false, loading: false,
filterMode: filterMode, filterMode: filterMode,
categoryMode: true, categoryMode: true,
@ -75,7 +75,7 @@ Discourse.ListController = Discourse.Controller.extend({
} }
return Discourse.TopicList.list(current).then(function(items) { return Discourse.TopicList.list(current).then(function(items) {
listController.setProperties({ self.setProperties({
loading: false, loading: false,
filterMode: filterMode, filterMode: filterMode,
draft: items.draft, draft: items.draft,

View File

@ -15,6 +15,10 @@ Discourse.ListTopicsController = Discourse.ObjectController.extend({
latest: Ember.computed.equal('filter', 'latest'), latest: Ember.computed.equal('filter', 'latest'),
topicListReloading: function() {
return (!this.get('controllers.list.loading')) && (!this.get('loaded'));
}.property('loaded', 'controllers.list.loading'),
categories: function() { categories: function() {
return Discourse.Category.list(); return Discourse.Category.list();
}.property(), }.property(),

View File

@ -5,7 +5,7 @@
{{#discourse-heading sortBy="default" sortOrder=sortOrder}} {{#discourse-heading sortBy="default" sortOrder=sortOrder}}
{{i18n topic.title}} {{i18n topic.title}}
{{/discourse-heading}} {{/discourse-heading}}
{{#discourse-heading}} {{#discourse-heading sortBy="category" sortOrder=sortOrder}}
{{i18n category_title}} {{i18n category_title}}
{{/discourse-heading}} {{/discourse-heading}}
{{#discourse-heading sortBy="posts" number=true sortOrder=sortOrder}} {{#discourse-heading sortBy="posts" number=true sortOrder=sortOrder}}

View File

@ -0,0 +1,3 @@
<div {{bindAttr class=":contents :loading loading::hidden"}}>
<div class='spinner'>{{i18n loading}}</div>
</div>

View File

@ -26,18 +26,7 @@
<div class="row"> <div class="row">
<div class="full-width"> <div class="full-width">
<div id='list-area'> <div id='list-area'>
{{#if loading}} {{discourse-topic-list-loading loading=loading}}
<div class='contents loading'>
<table id='topic-list'>
<tr>
<td colspan='8'>
<div class='spinner'>{{i18n loading}}</div>
</td>
</tr>
</table>
</div>
{{/if}}
{{outlet listView}} {{outlet listView}}
</div> </div>
</div> </div>

View File

@ -1,3 +1,5 @@
{{discourse-topic-list-loading loading=topicListReloading}}
{{#unless loading}} {{#unless loading}}
{{#if loaded}} {{#if loaded}}
<div class='contents'> <div class='contents'>
@ -16,17 +18,29 @@
{{#if currentUser}} {{#if currentUser}}
<th>&nbsp;</th> <th>&nbsp;</th>
{{/if}} {{/if}}
<th class='main-link'> {{#discourse-heading sortBy="default" sortOrder=sortOrder}}
{{i18n topic.title}} {{i18n topic.title}}
</th> {{/discourse-heading}}
{{#unless category}} {{#unless category}}
<th class='category'>{{i18n category_title}}</th> {{#discourse-heading sortBy="category" sortOrder=sortOrder}}
{{i18n category_title}}
{{/discourse-heading}}
{{/unless}} {{/unless}}
<th class='posters'>{{i18n top_contributors}}</th> {{#discourse-heading sortBy="posters" sortOrder=sortOrder}}
<th class='num posts'>{{i18n posts}}</th> {{i18n top_contributors}}
<th class='num likes'>{{i18n likes}}</th> {{/discourse-heading}}
<th class='num views'>{{i18n views}}</th> {{#discourse-heading sortBy="posts" number=true sortOrder=sortOrder}}
<th class='num activity' colspan='2'>{{i18n activity}}</th> {{i18n posts}}
{{/discourse-heading}}
{{#discourse-heading sortBy="likes" number=true sortOrder=sortOrder}}
{{i18n likes}}
{{/discourse-heading}}
{{#discourse-heading sortBy="views" number=true sortOrder=sortOrder}}
{{i18n views}}
{{/discourse-heading}}
{{#discourse-heading sortBy="activity" number=true colspan="2" sortOrder=sortOrder}}
{{i18n activity}}
{{/discourse-heading}}
</tr> </tr>
</thead> </thead>
@ -67,6 +81,5 @@
{{/if}} {{/if}}
</h3> </h3>
</footer> </footer>
{{/if}} {{/if}}
{{/unless}} {{/unless}}

View File

@ -178,7 +178,7 @@
width: 140px; width: 140px;
} }
.posters { .posters {
width: 150px; width: 170px;
> a { > a {
float: left; float: left;
margin-right: 4px; margin-right: 4px;
@ -206,7 +206,13 @@
@include unselectable; @include unselectable;
} }
.likes { .likes {
width: 50px; width: 65px;
}
.views {
width: 65px;
}
.posts {
width: 65px;
} }
.activity { .activity {
width: 50px; width: 50px;
@ -216,20 +222,6 @@
} }
} }
.paginated-topics-list {
#topic-list {
.posts {
width: 95px;
}
.likes {
width: 95px;
}
.views {
width: 95px;
}
}
}
#topic-list tbody tr.has-excerpt .star { #topic-list tbody tr.has-excerpt .star {
vertical-align: top; vertical-align: top;

View File

@ -24,7 +24,9 @@ class TopicQuery
'likes' => 'like_count', 'likes' => 'like_count',
'views' => 'views', 'views' => 'views',
'posts' => 'posts_count', 'posts' => 'posts_count',
'activity' => 'bumped_at' 'activity' => 'bumped_at',
'posters' => 'participant_count',
'category' => 'category_id'
} }
def initialize(user=nil, options={}) def initialize(user=nil, options={})
@ -173,10 +175,23 @@ class TopicQuery
# If we are sorting in the default order desc, we should consider including pinned # If we are sorting in the default order desc, we should consider including pinned
# topics. Otherwise, just use bumped_at. # topics. Otherwise, just use bumped_at.
if sort_column == 'default' if sort_column == 'default'
return default_ordering(result, options) if sort_dir == 'DESC' if sort_dir == 'DESC'
# If something requires a custom order, for example "unread" which sorts the least read
# to the top, do nothing
return result if options[:unordered]
# Otherwise apply our default ordering
return default_ordering(result, options)
end
sort_column = 'bumped_at' sort_column = 'bumped_at'
end end
# If we are sorting by category, actually use the name
if sort_column == 'category_id'
return result.references(:categories).order(TopicQuerySQL.order_by_category_sql(sort_dir))
end
result.order("topics.#{sort_column} #{sort_dir}") result.order("topics.#{sort_column} #{sort_dir}")
end end
@ -203,13 +218,10 @@ class TopicQuery
result = result.references(:categories) result = result.references(:categories)
end end
result = apply_ordering(result, options) unless options[:unordered] result = apply_ordering(result, options)
result = result.listable_topics.includes(category: :topic_only_relative_url) result = result.listable_topics.includes(category: :topic_only_relative_url)
result = result.where('categories.name is null or categories.name <> ?', options[:exclude_category]).references(:categories) if options[:exclude_category] result = result.where('categories.name is null or categories.name <> ?', options[:exclude_category]).references(:categories) if options[:exclude_category]
result = result.limit(options[:per_page]) unless options[:limit] == false result = result.limit(options[:per_page]) unless options[:limit] == false
result = result.visible if options[:visible] || @user.nil? || @user.regular? result = result.visible if options[:visible] || @user.nil? || @user.regular?
result = result.where('topics.id <> ?', options[:except_topic_id]).references(:topics) if options[:except_topic_id] result = result.where('topics.id <> ?', options[:except_topic_id]).references(:topics) if options[:except_topic_id]
@ -233,9 +245,7 @@ class TopicQuery
end end
def new_results(options={}) def new_results(options={})
result = TopicQuery.new_filter(default_results(options.reverse_merge(:unordered => true)), result = TopicQuery.new_filter(default_results(options), @user.treat_as_new_topic_start_date)
@user.treat_as_new_topic_start_date)
suggested_ordering(result, options) suggested_ordering(result, options)
end end

View File

@ -42,6 +42,10 @@ module TopicQuerySQL
end end
end end
def order_by_category_sql(dir)
"CASE WHEN categories.id = #{SiteSetting.uncategorized_category_id.to_i} THEN '' ELSE categories.name END #{dir}"
end
# If you've clearned the pin, use bumped_at, otherwise put it at the top # If you've clearned the pin, use bumped_at, otherwise put it at the top
def order_nocategory_with_pinned_sql def order_nocategory_with_pinned_sql
"CASE "CASE

View File

@ -65,6 +65,7 @@ describe TopicQuery do
views: 100, views: 100,
like_count: 66, like_count: 66,
posts_count: 3, posts_count: 3,
participant_count: 11,
bumped_at: 15.minutes.ago) bumped_at: 15.minutes.ago)
end end
let!(:pinned_topic) do let!(:pinned_topic) do
@ -73,6 +74,7 @@ describe TopicQuery do
views: 10, views: 10,
like_count: 100, like_count: 100,
posts_count: 5, posts_count: 5,
participant_count: 12,
pinned_at: 10.minutes.ago, pinned_at: 10.minutes.ago,
bumped_at: 10.minutes.ago) bumped_at: 10.minutes.ago)
end end
@ -83,6 +85,7 @@ describe TopicQuery do
like_count: 30, like_count: 30,
posts_count: 4, posts_count: 4,
archived: true, archived: true,
participant_count: 1,
bumped_at: 6.minutes.ago) bumped_at: 6.minutes.ago)
end end
let!(:invisible_topic) do let!(:invisible_topic) do
@ -92,6 +95,7 @@ describe TopicQuery do
like_count: 5, like_count: 5,
posts_count: 2, posts_count: 2,
visible: false, visible: false,
participant_count: 3,
bumped_at: 5.minutes.ago) bumped_at: 5.minutes.ago)
end end
let!(:closed_topic) do let!(:closed_topic) do
@ -101,6 +105,7 @@ describe TopicQuery do
like_count: 1, like_count: 1,
posts_count: 1, posts_count: 1,
closed: true, closed: true,
participant_count: 2,
bumped_at: 1.minute.ago) bumped_at: 1.minute.ago)
end end
@ -149,6 +154,14 @@ describe TopicQuery do
ids_in_order('views', false).should == [invisible_topic, closed_topic, pinned_topic, archived_topic, regular_topic].map(&:id) ids_in_order('views', false).should == [invisible_topic, closed_topic, pinned_topic, archived_topic, regular_topic].map(&:id)
end end
it "returns the topics in posters order if requested" do
ids_in_order('posters').should == [pinned_topic, regular_topic, invisible_topic, closed_topic, archived_topic].map(&:id)
end
it "returns the topics in reverse posters order if requested" do
ids_in_order('posters', false).should == [archived_topic, closed_topic, invisible_topic, regular_topic, pinned_topic].map(&:id)
end
end end
end end