categories can now be re-ordered

This commit is contained in:
Sam 2013-10-21 15:24:37 +11:00
parent 38a33a8c1b
commit 6067795780
9 changed files with 114 additions and 24 deletions

View file

@ -9,6 +9,12 @@
Discourse.ListCategoriesController = Discourse.ObjectController.extend({
needs: ['modal'],
actions: {
toggleOrdering: function(){
this.set("ordering",!this.get("ordering"));
}
},
categoriesEven: function() {
if (this.blank('categories')) return Em.A();
@ -31,6 +37,10 @@ Discourse.ListCategoriesController = Discourse.ObjectController.extend({
// clear a pinned topic
clearPin: function(topic) {
topic.clearPin();
},
moveCategory: function(categoryId, position){
this.get('model.categories').moveCategory(categoryId, position);
}
});

View file

@ -6,13 +6,26 @@
@namespace Discourse
@module Discourse
**/
Discourse.CategoryList = Discourse.Model.extend({});
Discourse.CategoryList = Ember.ArrayProxy.extend({
init: function() {
this.content = [];
this._super();
},
moveCategory: function(categoryId, position){
Discourse.ajax("/category/" + categoryId + "/move", {
type: 'POST',
data: {position: position}
});
}
});
Discourse.CategoryList.reopenClass({
categoriesFrom: function(result) {
var categories = Em.A();
var users = this.extractByKey(result.featured_users, Discourse.User);
var categories = Discourse.CategoryList.create();
var users = Discourse.Model.extractByKey(result.featured_users, Discourse.User);
_.each(result.category_list.categories,function(c) {

View file

@ -6,13 +6,19 @@
<th class='category'>{{i18n categories.category}}</th>
<th class='num topics'>{{i18n categories.topics}}</th>
<th class='num posts'>{{i18n categories.posts}}</th>
<th class='latest'>{{i18n categories.latest}}</th>
<th class='latest'>{{i18n categories.latest}}
<button title='{{i18n categories.toggle_ordering}}' class='btn toggle-admin no-text' {{action toggleOrdering}}><i class='icon icon-wrench'></i></button>
</th>
</tr>
</thead>
<tbody>
{{#each model.categories}}
<tr>
<td class='category'>{{categoryLink this}}
{{#collection contentBinding="model.categories"}}
<tr data-category_id='{{unbound id}}'>
<td class='category'>
{{#if controller.ordering}}
<i class="icon-reorder"></i>
{{/if}}
{{categoryLink this}}
{{#if unreadTopics}}
<a href={{unbound url}} class='badge new-posts badge-notification' title='{{i18n topic.unread_topics count="unreadTopics"}}'>{{unbound unreadTopics}}</a>
{{/if}}
@ -52,7 +58,7 @@
</td>
{{/with}}
</tr>
{{/each}}
{{/collection}}
</tbody>
</table>

View file

@ -0,0 +1,35 @@
Discourse.ListWideCategoriesView = Discourse.View.extend({
orderingChanged: function(){
if (this.get("controller.ordering")) {
this.enableOrdering();
} else {
this.disableOrdering();
}
}.observes("controller.ordering"),
rows: function() {
return $('#topic-list tbody');
},
enableOrdering: function(){
var self = this;
Em.run.next(function(){
self.rows().sortable({handle: '.icon-reorder'}).on('sortupdate',function(evt, data){
var tr = $(data.item);
var categoryId = tr.data('category_id');
var position = self.rows().find('tr').index(tr[0]);
self.get('controller').moveCategory(categoryId, position);
});
});
},
disableOrdering: function(){
this.rows().sortable("destroy").off('sortupdate');
},
willDestroyElement: function(){
this.disableOrdering();
}
});

View file

@ -8,8 +8,6 @@
// List controls
// --------------------------------------------------
#list-controls {
.nav {
float: left;
@ -96,8 +94,6 @@
font-size: 14px;
}
.star {
width: 20px;
padding-right: 0;
@ -203,6 +199,16 @@
}
#topic-list.categories {
th.latest {
position: relative;
}
th .toggle-admin {
position: absolute;
padding: 3px 8px;
font-size: 12px;
right: 5px;
top: 4px;
}
th.latest, td.latest {
padding-left: 12px;
}

View file

@ -15,9 +15,6 @@ class CategoriesController < ApplicationController
options[:latest_post_only] = params[:latest_post_only] || wide_mode
@list = CategoryList.new(guardian,options)
@list.draft_key = Draft::NEW_TOPIC
@list.draft_sequence = DraftSequence.current(current_user, Draft::NEW_TOPIC)
@list.draft = Draft.get(current_user, @list.draft_key, @list.draft_sequence) if current_user
@ -31,6 +28,18 @@ class CategoriesController < ApplicationController
end
end
def move
params.require("category_id")
params.require("position")
if category = Category.find(params["category_id"])
category.move_to(params["position"].to_i)
render json: success_json
else
render status: 500, json: failed_json
end
end
def show
render_serialized(@category, CategorySerializer)
end
@ -52,7 +61,8 @@ class CategoriesController < ApplicationController
def destroy
guardian.ensure_can_delete!(@category)
@category.destroy
render nothing: true
render json: success_json
end
private

View file

@ -48,12 +48,16 @@ class CategoryList
@categories = Category
.includes(:featured_users)
.secured(@guardian)
if latest_post_only?
@categories = @categories
.includes(:latest_post => {:topic => :last_poster} )
.order('position ASC')
else
@categories = @categories
.order('COALESCE(categories.topics_week, 0) DESC')
.order('COALESCE(categories.topics_month, 0) DESC')
.order('COALESCE(categories.topics_year, 0) DESC')
if latest_post_only?
@categories = @categories.includes(:latest_post => {:topic => :last_poster} )
end
@categories = @categories.to_a
@ -88,6 +92,7 @@ class CategoryList
end
# Add the uncategorized "magic" category
# TODO: remove this entire hack, not needed
def add_uncategorized
# Support for uncategorized topics
uncategorized_topics = Topic
@ -117,12 +122,15 @@ class CategoryList
# Find the appropriate place to insert it:
insert_at = nil
unless latest_post_only?
@categories.each_with_index do |c, idx|
if (uncategorized.topics_week || 0) > (c.topics_week || 0)
insert_at = idx
break
end
end
end
@categories.insert(insert_at || @categories.size, uncategorized)
end

View file

@ -189,6 +189,7 @@ en:
topics: "Topics"
latest: "Latest"
latest_by: "latest by"
toggle_ordering: "toggle ordering control"
user:
said: "{{username}} said:"

View file

@ -187,6 +187,7 @@ Discourse::Application.routes.draw do
resources :categories, :except => :show
get 'category/:id/show' => 'categories#show'
post 'category/:category_id/move' => 'categories#move', as: 'category_move'
get 'category/:category.rss' => 'list#category_feed', format: :rss, as: 'category_feed'
get 'category/:category' => 'list#category', as: 'category_list'