mirror of
https://github.com/discourse/discourse.git
synced 2025-02-09 04:44:59 +00:00
Enable column sorting main topic list
This commit is contained in:
parent
67041d1c6d
commit
968c0672ef
@ -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,
|
||||||
|
@ -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(),
|
||||||
|
@ -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}}
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
<div {{bindAttr class=":contents :loading loading::hidden"}}>
|
||||||
|
<div class='spinner'>{{i18n loading}}</div>
|
||||||
|
</div>
|
@ -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>
|
||||||
|
@ -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> </th>
|
<th> </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}}
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user