FIX: Couldn't access "Uncategorized" category from category list.

This commit is contained in:
Robin Ward 2013-05-27 14:15:20 -04:00
parent b1ef2ea1e1
commit 62a20f5655
10 changed files with 82 additions and 43 deletions

View file

@ -10,12 +10,6 @@ Discourse.Category = Discourse.Model.extend({
init: function() { init: function() {
this._super(); this._super();
if (!this.get('id') && this.get('name')) {
this.set('is_uncategorized', true);
if (!this.get('color')) this.set('color', Discourse.SiteSettings.uncategorized_color);
if (!this.get('text_color')) this.set('text_color', Discourse.SiteSettings.uncategorized_text_color);
}
this.set("availableGroups", Em.A(this.get("available_groups"))); this.set("availableGroups", Em.A(this.get("available_groups")));
this.set("groups", Em.A(this.groups)); this.set("groups", Em.A(this.groups));
}, },
@ -75,6 +69,19 @@ Discourse.Category = Discourse.Model.extend({
Discourse.Category.reopenClass({ Discourse.Category.reopenClass({
uncategorizedInstance: function() {
if (this.uncategorized) return this.uncategorized;
this.uncategorized = this.create({
slug: 'uncategorized',
name: Discourse.SiteSettings.uncategorized_name,
isUncategorized: true,
color: Discourse.SiteSettings.uncategorized_color,
text_color: Discourse.SiteSettings.uncategorized_text_color
});
return this.uncategorized;
},
list: function() { list: function() {
return Discourse.Site.instance().get('categories'); return Discourse.Site.instance().get('categories');
}, },

View file

@ -11,9 +11,10 @@ Discourse.CategoryList = Discourse.Model.extend({});
Discourse.CategoryList.reopenClass({ Discourse.CategoryList.reopenClass({
categoriesFrom: function(result) { categoriesFrom: function(result) {
var categories, users; var categories = Em.A();
categories = Em.A(); var users = this.extractByKey(result.featured_users, Discourse.User);
users = this.extractByKey(result.featured_users, Discourse.User);
result.category_list.categories.each(function(c) { result.category_list.categories.each(function(c) {
if (c.featured_user_ids) { if (c.featured_user_ids) {
c.featured_users = c.featured_user_ids.map(function(u) { c.featured_users = c.featured_user_ids.map(function(u) {
@ -25,7 +26,17 @@ Discourse.CategoryList.reopenClass({
return Discourse.Topic.create(t); return Discourse.Topic.create(t);
}); });
} }
return categories.pushObject(Discourse.Category.create(c));
if (c.is_uncategorized) {
var uncategorized = Discourse.Category.uncategorizedInstance();
uncategorized.setProperties({
topics: c.topics,
featured_users: c.featured_users
});
categories.pushObject(uncategorized);
} else {
categories.pushObject(Discourse.Category.create(c));
}
}); });
return categories; return categories;
}, },

View file

@ -41,6 +41,7 @@ Discourse.Site.reopenClass({
create: function(obj) { create: function(obj) {
var _this = this; var _this = this;
return Object.tap(this._super(obj), function(result) { return Object.tap(this._super(obj), function(result) {
if (result.categories) { if (result.categories) {
result.categories = result.categories.map(function(c) { result.categories = result.categories.map(function(c) {
return Discourse.Category.create(c); return Discourse.Category.create(c);

View file

@ -8,26 +8,24 @@
**/ **/
Discourse.ListCategoriesRoute = Discourse.Route.extend({ Discourse.ListCategoriesRoute = Discourse.Route.extend({
exit: function() { model: function() {
var listTopicsController = this.controllerFor('listTopics');
if (listTopicsController) listTopicsController.set('content', null);
return this.controllerFor('list').load('categories');
},
deactivate: function() {
this._super(); this._super();
this.controllerFor('list').set('canCreateCategory', false); this.controllerFor('list').set('canCreateCategory', false);
}, },
setupController: function(controller) { setupController: function(controller, categoryList) {
var listController, this.render('listCategories', { into: 'list', outlet: 'listView' });
_this = this; this.controllerFor('list').setProperties({
listController = this.controllerFor('list'); canCreateCategory: categoryList.get('can_create_category'),
listController.set('filterMode', 'categories'); canCreateTopic: categoryList.get('can_create_topic'),
listController.load('categories').then(function(categoryList) { category: null
_this.render('listCategories', {
into: 'list',
outlet: 'listView',
controller: 'listCategories'
});
listController.set('canCreateCategory', categoryList.get('can_create_category'));
listController.set('canCreateTopic', categoryList.get('can_create_topic'));
listController.set('category', null);
_this.controllerFor('listCategories').set('content', categoryList);
}); });
} }

View file

@ -12,6 +12,10 @@ Discourse.ListCategoryRoute = Discourse.FilteredListRoute.extend({
var categories = Discourse.Category.list(); var categories = Discourse.Category.list();
var slug = Em.get(params, 'slug'); var slug = Em.get(params, 'slug');
var uncategorized = Discourse.Category.uncategorizedInstance();
if (slug === uncategorized.get('slug')) return uncategorized;
var category = categories.findProperty('slug', Em.get(params, 'slug')) var category = categories.findProperty('slug', Em.get(params, 'slug'))
// In case the slug didn't work, try to find it by id instead. // In case the slug didn't work, try to find it by id instead.

View file

@ -5,7 +5,7 @@
<li {{bindAttr class="view.generalSelected:active"}}> <li {{bindAttr class="view.generalSelected:active"}}>
<a href="#" {{action selectGeneral target="view"}}>{{i18n category.general}}</a> <a href="#" {{action selectGeneral target="view"}}>{{i18n category.general}}</a>
</li> </li>
{{#unless is_uncategorized}} {{#unless isUncategorized}}
<li {{bindAttr class="view.securitySelected:active"}}> <li {{bindAttr class="view.securitySelected:active"}}>
<a href="#" {{action selectSecurity target="view"}}>{{i18n category.security}}</a> <a href="#" {{action selectSecurity target="view"}}>{{i18n category.security}}</a>
</li> </li>
@ -23,7 +23,7 @@
{{textField value=name placeholderKey="category.name_placeholder" maxlength="50"}} {{textField value=name placeholderKey="category.name_placeholder" maxlength="50"}}
</section> </section>
{{#unless is_uncategorized}} {{#unless isUncategorized}}
<section class='field'> <section class='field'>
<label>{{i18n category.description}}</label> <label>{{i18n category.description}}</label>
@ -59,7 +59,7 @@
</section> </section>
</form> </form>
</div> </div>
{{#unless is_uncategorized}} {{#unless isUncategorized}}
<div {{bindAttr class=":modal-tab :options-tab view.securitySelected::invisible"}}> <div {{bindAttr class=":modal-tab :options-tab view.securitySelected::invisible"}}>
<section class='field'> <section class='field'>
<label> <label>

View file

@ -70,7 +70,7 @@ Discourse.EditCategoryView = Discourse.ModalBodyView.extend({
title: function() { title: function() {
if (this.get('category.id')) return Em.String.i18n("category.edit_long"); if (this.get('category.id')) return Em.String.i18n("category.edit_long");
if (this.get('category.is_uncategorized')) return Em.String.i18n("category.edit_uncategorized"); if (this.get('category.isUncategorized')) return Em.String.i18n("category.edit_uncategorized");
return Em.String.i18n("category.create"); return Em.String.i18n("category.create");
}.property('category.id'), }.property('category.id'),
@ -81,7 +81,7 @@ Discourse.EditCategoryView = Discourse.ModalBodyView.extend({
buttonTitle: function() { buttonTitle: function() {
if (this.get('saving')) return Em.String.i18n("saving"); if (this.get('saving')) return Em.String.i18n("saving");
if (this.get('category.is_uncategorized')) return Em.String.i18n("save"); if (this.get('category.isUncategorized')) return Em.String.i18n("save");
return (this.get('category.id') ? Em.String.i18n("category.save") : Em.String.i18n("category.create")); return (this.get('category.id') ? Em.String.i18n("category.save") : Em.String.i18n("category.create"));
}.property('saving', 'category.id'), }.property('saving', 'category.id'),
@ -92,7 +92,7 @@ Discourse.EditCategoryView = Discourse.ModalBodyView.extend({
didInsertElement: function() { didInsertElement: function() {
this._super(); this._super();
if( this.get('category.id') ) { if (this.get('category.id')) {
this.set('loading', true); this.set('loading', true);
var categoryView = this; var categoryView = this;
@ -103,8 +103,8 @@ Discourse.EditCategoryView = Discourse.ModalBodyView.extend({
categoryView.set('id', categoryView.get('category.slug')); categoryView.set('id', categoryView.get('category.slug'));
categoryView.set('loading', false); categoryView.set('loading', false);
}); });
} else if( this.get('category.is_uncategorized') ) { } else if( this.get('category.isUncategorized') ) {
this.set('category', this.get('category')); this.set('category', Discourse.Category.uncategorizedInstance());
} else { } else {
this.set('category', Discourse.Category.create({ color: 'AB9364', text_color: 'FFFFFF', hotness: 5 })); this.set('category', Discourse.Category.create({ color: 'AB9364', text_color: 'FFFFFF', hotness: 5 }));
} }
@ -129,15 +129,19 @@ Discourse.EditCategoryView = Discourse.ModalBodyView.extend({
saveCategory: function() { saveCategory: function() {
var categoryView = this; var categoryView = this;
this.set('saving', true); this.set('saving', true);
if( this.get('category.is_uncategorized') ) {
if( this.get('category.isUncategorized') ) {
$.when( $.when(
Discourse.SiteSetting.update('uncategorized_color', this.get('category.color')), Discourse.SiteSetting.update('uncategorized_color', this.get('category.color')),
Discourse.SiteSetting.update('uncategorized_text_color', this.get('category.text_color')), Discourse.SiteSetting.update('uncategorized_text_color', this.get('category.text_color')),
Discourse.SiteSetting.update('uncategorized_name', this.get('category.name')) Discourse.SiteSetting.update('uncategorized_name', this.get('category.name'))
).then(function() { ).then(function(result) {
// success // success
$('#discourse-modal').modal('hide'); $('#discourse-modal').modal('hide');
Discourse.URL.redirectTo("/category/" + categoryView.get('category.name')); // We can't redirect to the uncategorized category on save because the slug
// might have changed.
Discourse.URL.redirectTo("/categories");
}, function(errors) { }, function(errors) {
// errors // errors
if(errors.length === 0) errors.push(Em.String.i18n("category.save_error")); if(errors.length === 0) errors.push(Em.String.i18n("category.save_error"));

View file

@ -36,10 +36,10 @@ class CategoryList
uncategorized = Category.new({name: SiteSetting.uncategorized_name, uncategorized = Category.new({name: SiteSetting.uncategorized_name,
slug: Slug.for(SiteSetting.uncategorized_name), slug: Slug.for(SiteSetting.uncategorized_name),
color: SiteSetting.uncategorized_color, color: SiteSetting.uncategorized_color,
text_color: SiteSetting.uncategorized_text_color, text_color: SiteSetting.uncategorized_text_color,
featured_topics: uncategorized_topics}.merge(totals)) featured_topics: uncategorized_topics}.merge(totals))
# Find the appropriate place to insert it: # Find the appropriate place to insert it:
insert_at = nil insert_at = nil

View file

@ -9,7 +9,8 @@ class CategoryDetailedSerializer < ApplicationSerializer
:topics_week, :topics_week,
:topics_month, :topics_month,
:topics_year, :topics_year,
:description :description,
:is_uncategorized
has_many :featured_users, serializer: BasicUserSerializer has_many :featured_users, serializer: BasicUserSerializer
has_many :featured_topics, serializer: CategoryTopicSerializer, embed: :objects, key: :topics has_many :featured_topics, serializer: CategoryTopicSerializer, embed: :objects, key: :topics
@ -26,4 +27,12 @@ class CategoryDetailedSerializer < ApplicationSerializer
object.topics_year || 0 object.topics_year || 0
end end
def is_uncategorized
name == SiteSetting.uncategorized_name
end
def include_is_uncategorized?
is_uncategorized
end
end end

View file

@ -2,7 +2,8 @@ class SiteSerializer < ApplicationSerializer
attributes :default_archetype, attributes :default_archetype,
:notification_types, :notification_types,
:post_types :post_types,
:uncategorized_slug
has_many :categories, serializer: BasicCategorySerializer, embed: :objects has_many :categories, serializer: BasicCategorySerializer, embed: :objects
has_many :post_action_types, embed: :objects has_many :post_action_types, embed: :objects
@ -18,4 +19,8 @@ class SiteSerializer < ApplicationSerializer
Post.types Post.types
end end
def uncategorized_slug
Slug.for(SiteSetting.uncategorized_name)
end
end end