From 6067795780b8e6c75d4e2feb7327330e04dda6d3 Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 21 Oct 2013 15:24:37 +1100 Subject: [PATCH] categories can now be re-ordered --- .../controllers/list_categories_controller.js | 10 ++++++ .../discourse/models/category_list.js | 19 ++++++++-- .../list/wide_categories.js.handlebars | 16 ++++++--- .../views/list/list_wide_categories_view.js | 35 +++++++++++++++++++ .../stylesheets/desktop/topic-list.scss | 14 +++++--- app/controllers/categories_controller.rb | 18 +++++++--- app/models/category_list.rb | 24 ++++++++----- config/locales/client.en.yml | 1 + config/routes.rb | 1 + 9 files changed, 114 insertions(+), 24 deletions(-) create mode 100644 app/assets/javascripts/discourse/views/list/list_wide_categories_view.js diff --git a/app/assets/javascripts/discourse/controllers/list_categories_controller.js b/app/assets/javascripts/discourse/controllers/list_categories_controller.js index 96722a0a4..29821a1a6 100644 --- a/app/assets/javascripts/discourse/controllers/list_categories_controller.js +++ b/app/assets/javascripts/discourse/controllers/list_categories_controller.js @@ -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); } }); diff --git a/app/assets/javascripts/discourse/models/category_list.js b/app/assets/javascripts/discourse/models/category_list.js index 838c1c1d2..31b4b9431 100644 --- a/app/assets/javascripts/discourse/models/category_list.js +++ b/app/assets/javascripts/discourse/models/category_list.js @@ -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) { diff --git a/app/assets/javascripts/discourse/templates/list/wide_categories.js.handlebars b/app/assets/javascripts/discourse/templates/list/wide_categories.js.handlebars index bf0fffd18..8dea442a7 100644 --- a/app/assets/javascripts/discourse/templates/list/wide_categories.js.handlebars +++ b/app/assets/javascripts/discourse/templates/list/wide_categories.js.handlebars @@ -6,13 +6,19 @@ {{i18n categories.category}} {{i18n categories.topics}} {{i18n categories.posts}} - {{i18n categories.latest}} + {{i18n categories.latest}} + + - {{#each model.categories}} - - {{categoryLink this}} + {{#collection contentBinding="model.categories"}} + + + {{#if controller.ordering}} + + {{/if}} + {{categoryLink this}} {{#if unreadTopics}} {{unbound unreadTopics}} {{/if}} @@ -52,7 +58,7 @@ {{/with}} - {{/each}} + {{/collection}} diff --git a/app/assets/javascripts/discourse/views/list/list_wide_categories_view.js b/app/assets/javascripts/discourse/views/list/list_wide_categories_view.js new file mode 100644 index 000000000..508d2b1be --- /dev/null +++ b/app/assets/javascripts/discourse/views/list/list_wide_categories_view.js @@ -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(); + } + +}); diff --git a/app/assets/stylesheets/desktop/topic-list.scss b/app/assets/stylesheets/desktop/topic-list.scss index e9abe83cf..f36ebd5d9 100644 --- a/app/assets/stylesheets/desktop/topic-list.scss +++ b/app/assets/stylesheets/desktop/topic-list.scss @@ -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; } diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb index 1fe45e8b6..e33aeb43c 100644 --- a/app/controllers/categories_controller.rb +++ b/app/controllers/categories_controller.rb @@ -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 diff --git a/app/models/category_list.rb b/app/models/category_list.rb index 641dd2d8c..04013cd45 100644 --- a/app/models/category_list.rb +++ b/app/models/category_list.rb @@ -48,12 +48,16 @@ class CategoryList @categories = Category .includes(:featured_users) .secured(@guardian) - .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} ) + @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') 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,10 +122,13 @@ class CategoryList # Find the appropriate place to insert it: insert_at = nil - @categories.each_with_index do |c, idx| - if (uncategorized.topics_week || 0) > (c.topics_week || 0) - insert_at = idx - break + + 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 diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 02f1a0deb..c26c25794 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -189,6 +189,7 @@ en: topics: "Topics" latest: "Latest" latest_by: "latest by" + toggle_ordering: "toggle ordering control" user: said: "{{username}} said:" diff --git a/config/routes.rb b/config/routes.rb index 83309bcdb..0d5d73415 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -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'