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.
**/
load: function(filterMode) {
var listController = this;
var self = this;
this.set('loading', true);
var trackingState = Discourse.TopicTrackingState.current();
if (filterMode === 'categories') {
return Discourse.CategoryList.list(filterMode).then(function(items) {
listController.setProperties({
self.setProperties({
loading: false,
filterMode: filterMode,
categoryMode: true,
@ -75,7 +75,7 @@ Discourse.ListController = Discourse.Controller.extend({
}
return Discourse.TopicList.list(current).then(function(items) {
listController.setProperties({
self.setProperties({
loading: false,
filterMode: filterMode,
draft: items.draft,

View File

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

View File

@ -5,7 +5,7 @@
{{#discourse-heading sortBy="default" sortOrder=sortOrder}}
{{i18n topic.title}}
{{/discourse-heading}}
{{#discourse-heading}}
{{#discourse-heading sortBy="category" sortOrder=sortOrder}}
{{i18n category_title}}
{{/discourse-heading}}
{{#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="full-width">
<div id='list-area'>
{{#if loading}}
<div class='contents loading'>
<table id='topic-list'>
<tr>
<td colspan='8'>
<div class='spinner'>{{i18n loading}}</div>
</td>
</tr>
</table>
</div>
{{/if}}
{{discourse-topic-list-loading loading=loading}}
{{outlet listView}}
</div>
</div>

View File

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

View File

@ -178,7 +178,7 @@
width: 140px;
}
.posters {
width: 150px;
width: 170px;
> a {
float: left;
margin-right: 4px;
@ -206,7 +206,13 @@
@include unselectable;
}
.likes {
width: 50px;
width: 65px;
}
.views {
width: 65px;
}
.posts {
width: 65px;
}
.activity {
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 {
vertical-align: top;

View File

@ -24,7 +24,9 @@ class TopicQuery
'likes' => 'like_count',
'views' => 'views',
'posts' => 'posts_count',
'activity' => 'bumped_at'
'activity' => 'bumped_at',
'posters' => 'participant_count',
'category' => 'category_id'
}
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
# topics. Otherwise, just use bumped_at.
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'
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}")
end
@ -203,13 +218,10 @@ class TopicQuery
result = result.references(:categories)
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.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.visible if options[:visible] || @user.nil? || @user.regular?
result = result.where('topics.id <> ?', options[:except_topic_id]).references(:topics) if options[:except_topic_id]
@ -233,9 +245,7 @@ class TopicQuery
end
def new_results(options={})
result = TopicQuery.new_filter(default_results(options.reverse_merge(:unordered => true)),
@user.treat_as_new_topic_start_date)
result = TopicQuery.new_filter(default_results(options), @user.treat_as_new_topic_start_date)
suggested_ordering(result, options)
end

View File

@ -42,6 +42,10 @@ module TopicQuerySQL
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
def order_nocategory_with_pinned_sql
"CASE

View File

@ -65,6 +65,7 @@ describe TopicQuery do
views: 100,
like_count: 66,
posts_count: 3,
participant_count: 11,
bumped_at: 15.minutes.ago)
end
let!(:pinned_topic) do
@ -73,6 +74,7 @@ describe TopicQuery do
views: 10,
like_count: 100,
posts_count: 5,
participant_count: 12,
pinned_at: 10.minutes.ago,
bumped_at: 10.minutes.ago)
end
@ -83,6 +85,7 @@ describe TopicQuery do
like_count: 30,
posts_count: 4,
archived: true,
participant_count: 1,
bumped_at: 6.minutes.ago)
end
let!(:invisible_topic) do
@ -92,6 +95,7 @@ describe TopicQuery do
like_count: 5,
posts_count: 2,
visible: false,
participant_count: 3,
bumped_at: 5.minutes.ago)
end
let!(:closed_topic) do
@ -101,6 +105,7 @@ describe TopicQuery do
like_count: 1,
posts_count: 1,
closed: true,
participant_count: 2,
bumped_at: 1.minute.ago)
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)
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