From 5d46478e382c305dc47a2a10971a689ba87f5946 Mon Sep 17 00:00:00 2001
From: Neil Lalonde <neillalonde@gmail.com>
Date: Tue, 9 Apr 2013 18:22:13 -0400
Subject: [PATCH] Add UI to delete an empty category

---
 .../controllers/list_categories_controller.js |  4 +-
 .../discourse/controllers/list_controller.js  | 14 +++++++
 .../templates/list/list.js.handlebars         |  4 ++
 .../modal/edit_category.js.handlebars         |  3 ++
 .../views/modal/edit_category_view.js         | 38 ++++++++++++++++++-
 .../application/topic-list.css.scss           |  1 +
 config/locales/client.en.yml                  |  3 +-
 7 files changed, 62 insertions(+), 5 deletions(-)

diff --git a/app/assets/javascripts/discourse/controllers/list_categories_controller.js b/app/assets/javascripts/discourse/controllers/list_categories_controller.js
index acac8d914..2eb5aa88e 100644
--- a/app/assets/javascripts/discourse/controllers/list_categories_controller.js
+++ b/app/assets/javascripts/discourse/controllers/list_categories_controller.js
@@ -5,7 +5,7 @@
   @extends Discourse.ObjectController
   @namespace Discourse
   @module Discourse
-**/ 
+**/
 Discourse.ListCategoriesController = Discourse.ObjectController.extend({
   needs: ['modal'],
 
@@ -37,7 +37,7 @@ Discourse.ListCategoriesController = Discourse.ObjectController.extend({
     u = Discourse.get('currentUser');
     return u && u.admin;
   }).property()
-  
+
 });
 
 
diff --git a/app/assets/javascripts/discourse/controllers/list_controller.js b/app/assets/javascripts/discourse/controllers/list_controller.js
index 046df79dc..9c9bc4b42 100644
--- a/app/assets/javascripts/discourse/controllers/list_controller.js
+++ b/app/assets/javascripts/discourse/controllers/list_controller.js
@@ -90,6 +90,20 @@ Discourse.ListController = Discourse.Controller.extend({
   createCategory: function() {
     var _ref;
     return (_ref = this.get('controllers.modal')) ? _ref.show(Discourse.EditCategoryView.create()) : void 0;
+  },
+
+  canEditCategory: function() {
+    if( this.present('category') ) {
+      var u = Discourse.get('currentUser');
+      return u && u.admin;
+    } else {
+      return false;
+    }
+  }.property('category'),
+
+  editCategory: function() {
+    this.get('controllers.modal').show(Discourse.EditCategoryView.create({ category: this.get('category') }));
+    return false;
   }
 
 });
diff --git a/app/assets/javascripts/discourse/templates/list/list.js.handlebars b/app/assets/javascripts/discourse/templates/list/list.js.handlebars
index c294ab930..da76a4f67 100644
--- a/app/assets/javascripts/discourse/templates/list/list.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/list/list.js.handlebars
@@ -10,6 +10,10 @@
       <button class='btn btn-default' {{action createTopic target="controller"}}><i class='icon icon-plus'></i>{{view.createTopicText}}</button>
     {{/if}}
 
+    {{#if controller.canEditCategory}}
+      <button class='btn btn-default' {{action editCategory target="controller"}}>{{i18n category.edit_long}}</button>
+    {{/if}}
+
     {{#if controller.canCreateCategory}}
       <button class='btn btn-default' {{action createCategory target="controller"}}><i class='icon icon-plus'></i>{{i18n category.create}}</button>
     {{/if}}
diff --git a/app/assets/javascripts/discourse/templates/modal/edit_category.js.handlebars b/app/assets/javascripts/discourse/templates/modal/edit_category.js.handlebars
index 06c691f6b..4e5cc6757 100644
--- a/app/assets/javascripts/discourse/templates/modal/edit_category.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/modal/edit_category.js.handlebars
@@ -52,6 +52,9 @@
   </div>
   <div class="modal-footer">
     <button class='btn btn-primary' {{bindAttr disabled="view.disabled"}} {{action saveCategory target="view"}}>{{view.buttonTitle}}</button>
+    {{#if view.deleteVisible}}
+      <button class='btn btn-danger pull-right' {{bindAttr disabled="view.deleteDisabled"}} {{action deleteCategory target="view"}}><i class="icon icon-trash"></i>{{view.deleteButtonTitle}}</button>
+    {{/if}}
   </div>
 
 {{/with}}
\ No newline at end of file
diff --git a/app/assets/javascripts/discourse/views/modal/edit_category_view.js b/app/assets/javascripts/discourse/views/modal/edit_category_view.js
index 43312e7dc..6b4a9a38e 100644
--- a/app/assets/javascripts/discourse/views/modal/edit_category_view.js
+++ b/app/assets/javascripts/discourse/views/modal/edit_category_view.js
@@ -14,11 +14,19 @@ Discourse.EditCategoryView = Discourse.ModalBodyView.extend({
   foregroundColors: ['FFFFFF', '000000'],
 
   disabled: function() {
-    if (this.get('saving')) return true;
+    if (this.get('saving') || this.get('deleting')) return true;
     if (!this.get('category.name')) return true;
     if (!this.get('category.color')) return true;
     return false;
-  }.property('category.name', 'category.color'),
+  }.property('category.name', 'category.color', 'deleting'),
+
+  deleteVisible: function() {
+    return (this.get('category.id') && this.get('category.topic_count') === 0);
+  }.property('category.id', 'category.topic_count'),
+
+  deleteDisabled: function() {
+    return (this.get('deleting') || this.get('saving') || false);
+  }.property('disabled', 'saving', 'deleting'),
 
   colorStyle: function() {
     return "background-color: #" + (this.get('category.color')) + "; color: #" + (this.get('category.text_color')) + ";";
@@ -52,6 +60,10 @@ Discourse.EditCategoryView = Discourse.ModalBodyView.extend({
     return this.get('title');
   }.property('title', 'saving'),
 
+  deleteButtonTitle: function() {
+    return Em.String.i18n('category.delete');
+  }.property(),
+
   didInsertElement: function() {
     this._super();
 
@@ -81,6 +93,28 @@ Discourse.EditCategoryView = Discourse.ModalBodyView.extend({
       categoryView.displayErrors(errors);
       categoryView.set('saving', false);
     });
+  },
+
+  deleteCategory: function() {
+    var categoryView = this;
+    this.set('deleting', true);
+    $('#discourse-modal').modal('hide');
+    bootbox.confirm(Em.String.i18n("category.delete_confirm"), Em.String.i18n("no_value"), Em.String.i18n("yes_value"), function(result) {
+      if (result) {
+        categoryView.get('category').destroy().then(function(){
+          // success
+          window.location = Discourse.getURL("/categories");
+        }, function(jqXHR){
+          // error
+          $('#discourse-modal').modal('show');
+          categoryView.displayErrors([Em.String.i18n("category.delete_error")]);
+          categoryView.set('deleting', false);
+        });
+      } else {
+        $('#discourse-modal').modal('show');
+        categoryView.set('deleting', false);
+      }
+    });
   }
 
 });
diff --git a/app/assets/stylesheets/application/topic-list.css.scss b/app/assets/stylesheets/application/topic-list.css.scss
index 2a18845ce..1e962c779 100755
--- a/app/assets/stylesheets/application/topic-list.css.scss
+++ b/app/assets/stylesheets/application/topic-list.css.scss
@@ -15,6 +15,7 @@
   }
   .btn {
     float: right;
+    margin-left: 8px;
   }
 }
 
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 99cb7906c..425b7e6b3 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -700,7 +700,8 @@ en:
       foreground_color: "Foreground color"
       name_placeholder: "Should be short and succinct."
       color_placeholder: "Any web color"
-      delete_confirm: "Are you sure you want to delete that category?"
+      delete_confirm: "Are you sure you want to delete this category?"
+      delete_error: "There was an error deleting the category."
       list: "List Categories"
       no_description: "There is no description for this category."
       change_in_category_topic: "visit category topic to edit the description"