From 462dcadd01f0c03b83761b2a58b28baa814a61e0 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Wed, 2 Jul 2014 15:10:39 -0400 Subject: [PATCH] FEATURE: Subcategory list on parent subcategory page. --- .../discourse/components/bread-crumbs.js.es6 | 5 +- .../components/category-title-link.js.es6 | 21 ++++++++ .../controllers/navigation/categories.js.es6 | 2 +- .../controllers/navigation/category.js.es6 | 5 ++ .../javascripts/discourse/ember/resolver.js | 4 ++ .../dynamic-route-builders.js.es6 | 1 + .../discourse/models/category_list.js | 11 +++- .../routes/build-category-route.js.es6 | 53 ++++++++++++++----- .../templates/discovery.js.handlebars | 9 ++++ .../discovery/categories.js.handlebars | 11 +--- .../navigation/category.js.handlebars | 5 +- app/controllers/categories_controller.rb | 3 +- app/models/category_list.rb | 32 ++++++----- 13 files changed, 119 insertions(+), 43 deletions(-) create mode 100644 app/assets/javascripts/discourse/components/category-title-link.js.es6 diff --git a/app/assets/javascripts/discourse/components/bread-crumbs.js.es6 b/app/assets/javascripts/discourse/components/bread-crumbs.js.es6 index 2e59c25a5..e61d5b8cf 100644 --- a/app/assets/javascripts/discourse/components/bread-crumbs.js.es6 +++ b/app/assets/javascripts/discourse/components/bread-crumbs.js.es6 @@ -29,12 +29,13 @@ export default Ember.Component.extend({ }.property('category', 'parentCategory'), childCategories: function() { + if (this.get('hideSubcategories')) { return []; } var firstCategory = this.get('firstCategory'); - if (!firstCategory) { return; } + if (!firstCategory) { return []; } return this.get('categories').filter(function (c) { return c.get('parentCategory') === firstCategory; }); - }.property('firstCategory') + }.property('firstCategory', 'hideSubcategories') }); diff --git a/app/assets/javascripts/discourse/components/category-title-link.js.es6 b/app/assets/javascripts/discourse/components/category-title-link.js.es6 new file mode 100644 index 000000000..96de552c1 --- /dev/null +++ b/app/assets/javascripts/discourse/components/category-title-link.js.es6 @@ -0,0 +1,21 @@ +export default Em.Component.extend({ + tagName: 'h3', + + render: function(buffer) { + var category = this.get('category'), + logoUrl = category.get('logo_url'); + + if (category.get('read_restricted')) { + buffer.push(" "); + } + + buffer.push(""); + + if (Em.isEmpty(logoUrl)) { + buffer.push(Handlebars.Utils.escapeExpression(category.get('name'))); + } else { + buffer.push(""); + } + buffer.push(""); + } +}); diff --git a/app/assets/javascripts/discourse/controllers/navigation/categories.js.es6 b/app/assets/javascripts/discourse/controllers/navigation/categories.js.es6 index bc7b48999..8276b094c 100644 --- a/app/assets/javascripts/discourse/controllers/navigation/categories.js.es6 +++ b/app/assets/javascripts/discourse/controllers/navigation/categories.js.es6 @@ -1,3 +1,3 @@ import NavigationDefaultController from 'discourse/controllers/navigation/default'; -export default NavigationDefaultController.extend({}); +export default NavigationDefaultController.extend(); diff --git a/app/assets/javascripts/discourse/controllers/navigation/category.js.es6 b/app/assets/javascripts/discourse/controllers/navigation/category.js.es6 index 3f9289cd0..4abaf1da2 100644 --- a/app/assets/javascripts/discourse/controllers/navigation/category.js.es6 +++ b/app/assets/javascripts/discourse/controllers/navigation/category.js.es6 @@ -1,7 +1,12 @@ import NavigationDefaultController from 'discourse/controllers/navigation/default'; export default NavigationDefaultController.extend({ + subcategoryListSetting: Discourse.computed.setting('show_subcategory_list'), + showingParentCategory: Em.computed.none('category.parentCategory'), + showingSubcategoryList: Em.computed.and('subcategoryListSetting', 'showingParentCategory'), + navItems: function() { + if (this.get('showingSubcategoryList')) { return []; } return Discourse.NavItem.buildList(this.get('category'), { noSubcategories: this.get('noSubcategories') }); }.property('category', 'noSubcategories') }); diff --git a/app/assets/javascripts/discourse/ember/resolver.js b/app/assets/javascripts/discourse/ember/resolver.js index 831fc397b..5e7eec583 100644 --- a/app/assets/javascripts/discourse/ember/resolver.js +++ b/app/assets/javascripts/discourse/ember/resolver.js @@ -77,6 +77,10 @@ Discourse.Resolver = Ember.DefaultResolver.extend({ return this.customResolve(parsedName) || this._super(parsedName); }, + resolveRoute: function(parsedName) { + return this.customResolve(parsedName) || this._super(parsedName); + }, + /** Attaches a view and wires up the container properly diff --git a/app/assets/javascripts/discourse/initializers/dynamic-route-builders.js.es6 b/app/assets/javascripts/discourse/initializers/dynamic-route-builders.js.es6 index 63434dda8..67f7fc6f6 100644 --- a/app/assets/javascripts/discourse/initializers/dynamic-route-builders.js.es6 +++ b/app/assets/javascripts/discourse/initializers/dynamic-route-builders.js.es6 @@ -3,6 +3,7 @@ import buildTopicRoute from 'discourse/routes/build-topic-route'; export default { name: 'dynamic-route-builders', + after: 'register-discourse-location', initialize: function(container, app) { app.DiscoveryCategoryRoute = buildCategoryRoute('latest'); diff --git a/app/assets/javascripts/discourse/models/category_list.js b/app/assets/javascripts/discourse/models/category_list.js index 5048316ed..d9c98d7c1 100644 --- a/app/assets/javascripts/discourse/models/category_list.js +++ b/app/assets/javascripts/discourse/models/category_list.js @@ -7,7 +7,6 @@ @module Discourse **/ Discourse.CategoryList = Ember.ArrayProxy.extend({ - init: function() { this.content = []; this._super(); @@ -22,7 +21,6 @@ Discourse.CategoryList = Ember.ArrayProxy.extend({ }); Discourse.CategoryList.reopenClass({ - categoriesFrom: function(result) { var categories = Discourse.CategoryList.create(), users = Discourse.Model.extractByKey(result.featured_users, Discourse.User), @@ -55,6 +53,15 @@ Discourse.CategoryList.reopenClass({ return categories; }, + listForParent: function(category) { + var self = this; + return Discourse.ajax('/categories.json?parent_category_id=' + category.get('id')).then(function(result) { + return Discourse.CategoryList.create({ + categories: self.categoriesFrom(result) + }); + }); + }, + list: function() { var self = this; diff --git a/app/assets/javascripts/discourse/routes/build-category-route.js.es6 b/app/assets/javascripts/discourse/routes/build-category-route.js.es6 index dbca1126b..466600e50 100644 --- a/app/assets/javascripts/discourse/routes/build-category-route.js.es6 +++ b/app/assets/javascripts/discourse/routes/build-category-route.js.es6 @@ -1,8 +1,8 @@ // A helper function to create a category route with parameters export default function(filter, params) { return Discourse.Route.extend({ - model: function(params) { - return Discourse.Category.findBySlug(params.slug, params.parentSlug); + model: function(modelParams) { + return Discourse.Category.findBySlug(modelParams.slug, modelParams.parentSlug); }, afterModel: function(model, transaction) { @@ -11,21 +11,44 @@ export default function(filter, params) { return; } - var self = this, - noSubcategories = params && !!params.no_subcategories, - filterMode = "category/" + Discourse.Category.slugFor(model) + (noSubcategories ? "/none" : "") + "/l/" + filter, - listFilter = "category/" + Discourse.Category.slugFor(model) + "/l/" + filter; - this.controllerFor('search').set('searchContext', model.get('searchContext')); + this._setupNavigation(model); + return Em.RSVP.all([this._createSubcategoryList(model), + this._retrieveTopicList(model, transaction)]); + }, - var opts = { category: model, filterMode: filterMode }; - opts.noSubcategories = params && params.no_subcategories; - opts.canEditCategory = Discourse.User.currentProp('staff'); + _setupNavigation: function(model) { + var noSubcategories = params && !!params.no_subcategories, + filterMode = "category/" + Discourse.Category.slugFor(model) + (noSubcategories ? "/none" : "") + "/l/" + filter; - opts.canChangeCategoryNotificationLevel = Discourse.User.current(); - this.controllerFor('navigation/category').setProperties(opts); + this.controllerFor('navigation/category').setProperties({ + category: model, + filterMode: filterMode, + noSubcategories: params && params.no_subcategories, + canEditCategory: Discourse.User.currentProp('staff'), + canChangeCategoryNotificationLevel: Discourse.User.current() + }); + }, + + _createSubcategoryList: function(model) { + this._categoryList = null; + if (Em.isNone(model.get('parentCategory')) && Discourse.SiteSettings.show_subcategory_list) { + var self = this; + return Discourse.CategoryList.listForParent(model).then(function(list) { + console.log('loaded list'); + self._categoryList = list; + }); + } + + // If we're not loading a subcategory list just resolve + return Em.RSVP.resolve(); + }, + + _retrieveTopicList: function(model, transaction) { + var queryParams = transaction.queryParams, + listFilter = "category/" + Discourse.Category.slugFor(model) + "/l/" + filter, + self = this; - var queryParams = transaction.queryParams; params = params || {}; if (queryParams && queryParams.order) { params.order = queryParams.order; } @@ -67,6 +90,10 @@ export default function(filter, params) { renderTemplate: function() { this.render('navigation/category', { outlet: 'navigation-bar' }); + + if (this._categoryList) { + this.render('discovery/categories', { outlet: 'header-list-container', model: this._categoryList }); + } this.render('discovery/topics', { controller: 'discovery/topics', outlet: 'list-container' }); }, diff --git a/app/assets/javascripts/discourse/templates/discovery.js.handlebars b/app/assets/javascripts/discourse/templates/discovery.js.handlebars index 14b79688c..c4ba98bed 100644 --- a/app/assets/javascripts/discourse/templates/discovery.js.handlebars +++ b/app/assets/javascripts/discourse/templates/discovery.js.handlebars @@ -14,7 +14,16 @@
{{i18n loading}}
+
+
+
+
+ {{outlet header-list-container}} +
+
+
+
diff --git a/app/assets/javascripts/discourse/templates/discovery/categories.js.handlebars b/app/assets/javascripts/discourse/templates/discovery/categories.js.handlebars index d1bf19be3..7f34f9d2f 100644 --- a/app/assets/javascripts/discourse/templates/discovery/categories.js.handlebars +++ b/app/assets/javascripts/discourse/templates/discovery/categories.js.handlebars @@ -20,16 +20,7 @@
{{#if controller.ordering}}{{/if}} -

- {{#if read_restricted}}{{/if}} - {{#link-to 'discovery.parentCategory' this}} - {{#if logo_url}} - - {{else}} - {{unbound name}} - {{/if}} - {{/link-to}} -

+ {{category-title-link category=this}} {{#if unreadTopics}} {{unbound unreadTopics}} {{/if}} diff --git a/app/assets/javascripts/discourse/templates/navigation/category.js.handlebars b/app/assets/javascripts/discourse/templates/navigation/category.js.handlebars index 6ed3e444e..be683ebff 100644 --- a/app/assets/javascripts/discourse/templates/navigation/category.js.handlebars +++ b/app/assets/javascripts/discourse/templates/navigation/category.js.handlebars @@ -1,4 +1,7 @@ -{{bread-crumbs categories=categories category=category noSubcategories=noSubcategories}} +{{bread-crumbs categories=categories + category=category + noSubcategories=noSubcategories + hideSubcategories=showingSubcategoryList}}