mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-27 17:46:05 -05:00
categories can now be re-ordered
This commit is contained in:
parent
38a33a8c1b
commit
6067795780
9 changed files with 114 additions and 24 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
});
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -189,6 +189,7 @@ en:
|
|||
topics: "Topics"
|
||||
latest: "Latest"
|
||||
latest_by: "latest by"
|
||||
toggle_ordering: "toggle ordering control"
|
||||
|
||||
user:
|
||||
said: "{{username}} said:"
|
||||
|
|
|
@ -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'
|
||||
|
|
Loading…
Reference in a new issue