mirror of
https://github.com/discourse/discourse.git
synced 2024-11-26 02:40:53 -06:00
FEATURE: Subcategory list on parent subcategory page.
This commit is contained in:
parent
4592916026
commit
462dcadd01
@ -29,12 +29,13 @@ export default Ember.Component.extend({
|
|||||||
}.property('category', 'parentCategory'),
|
}.property('category', 'parentCategory'),
|
||||||
|
|
||||||
childCategories: function() {
|
childCategories: function() {
|
||||||
|
if (this.get('hideSubcategories')) { return []; }
|
||||||
var firstCategory = this.get('firstCategory');
|
var firstCategory = this.get('firstCategory');
|
||||||
if (!firstCategory) { return; }
|
if (!firstCategory) { return []; }
|
||||||
|
|
||||||
return this.get('categories').filter(function (c) {
|
return this.get('categories').filter(function (c) {
|
||||||
return c.get('parentCategory') === firstCategory;
|
return c.get('parentCategory') === firstCategory;
|
||||||
});
|
});
|
||||||
}.property('firstCategory')
|
}.property('firstCategory', 'hideSubcategories')
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -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("<i class='fa fa-group'></i> ");
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.push("<a href='" + Discourse.getURL('/category/') + Discourse.Category.slugFor(category) + "'>");
|
||||||
|
|
||||||
|
if (Em.isEmpty(logoUrl)) {
|
||||||
|
buffer.push(Handlebars.Utils.escapeExpression(category.get('name')));
|
||||||
|
} else {
|
||||||
|
buffer.push("<img src='" + logoUrl + "' class='category-logo'>");
|
||||||
|
}
|
||||||
|
buffer.push("</a>");
|
||||||
|
}
|
||||||
|
});
|
@ -1,3 +1,3 @@
|
|||||||
import NavigationDefaultController from 'discourse/controllers/navigation/default';
|
import NavigationDefaultController from 'discourse/controllers/navigation/default';
|
||||||
|
|
||||||
export default NavigationDefaultController.extend({});
|
export default NavigationDefaultController.extend();
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
import NavigationDefaultController from 'discourse/controllers/navigation/default';
|
import NavigationDefaultController from 'discourse/controllers/navigation/default';
|
||||||
|
|
||||||
export default NavigationDefaultController.extend({
|
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() {
|
navItems: function() {
|
||||||
|
if (this.get('showingSubcategoryList')) { return []; }
|
||||||
return Discourse.NavItem.buildList(this.get('category'), { noSubcategories: this.get('noSubcategories') });
|
return Discourse.NavItem.buildList(this.get('category'), { noSubcategories: this.get('noSubcategories') });
|
||||||
}.property('category', 'noSubcategories')
|
}.property('category', 'noSubcategories')
|
||||||
});
|
});
|
||||||
|
@ -77,6 +77,10 @@ Discourse.Resolver = Ember.DefaultResolver.extend({
|
|||||||
return this.customResolve(parsedName) || this._super(parsedName);
|
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
|
Attaches a view and wires up the container properly
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import buildTopicRoute from 'discourse/routes/build-topic-route';
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'dynamic-route-builders',
|
name: 'dynamic-route-builders',
|
||||||
|
after: 'register-discourse-location',
|
||||||
|
|
||||||
initialize: function(container, app) {
|
initialize: function(container, app) {
|
||||||
app.DiscoveryCategoryRoute = buildCategoryRoute('latest');
|
app.DiscoveryCategoryRoute = buildCategoryRoute('latest');
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
@module Discourse
|
@module Discourse
|
||||||
**/
|
**/
|
||||||
Discourse.CategoryList = Ember.ArrayProxy.extend({
|
Discourse.CategoryList = Ember.ArrayProxy.extend({
|
||||||
|
|
||||||
init: function() {
|
init: function() {
|
||||||
this.content = [];
|
this.content = [];
|
||||||
this._super();
|
this._super();
|
||||||
@ -22,7 +21,6 @@ Discourse.CategoryList = Ember.ArrayProxy.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
Discourse.CategoryList.reopenClass({
|
Discourse.CategoryList.reopenClass({
|
||||||
|
|
||||||
categoriesFrom: function(result) {
|
categoriesFrom: function(result) {
|
||||||
var categories = Discourse.CategoryList.create(),
|
var categories = Discourse.CategoryList.create(),
|
||||||
users = Discourse.Model.extractByKey(result.featured_users, Discourse.User),
|
users = Discourse.Model.extractByKey(result.featured_users, Discourse.User),
|
||||||
@ -55,6 +53,15 @@ Discourse.CategoryList.reopenClass({
|
|||||||
return categories;
|
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() {
|
list: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
// A helper function to create a category route with parameters
|
// A helper function to create a category route with parameters
|
||||||
export default function(filter, params) {
|
export default function(filter, params) {
|
||||||
return Discourse.Route.extend({
|
return Discourse.Route.extend({
|
||||||
model: function(params) {
|
model: function(modelParams) {
|
||||||
return Discourse.Category.findBySlug(params.slug, params.parentSlug);
|
return Discourse.Category.findBySlug(modelParams.slug, modelParams.parentSlug);
|
||||||
},
|
},
|
||||||
|
|
||||||
afterModel: function(model, transaction) {
|
afterModel: function(model, transaction) {
|
||||||
@ -11,21 +11,44 @@ export default function(filter, params) {
|
|||||||
return;
|
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.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 };
|
_setupNavigation: function(model) {
|
||||||
opts.noSubcategories = params && params.no_subcategories;
|
var noSubcategories = params && !!params.no_subcategories,
|
||||||
opts.canEditCategory = Discourse.User.currentProp('staff');
|
filterMode = "category/" + Discourse.Category.slugFor(model) + (noSubcategories ? "/none" : "") + "/l/" + filter;
|
||||||
|
|
||||||
opts.canChangeCategoryNotificationLevel = Discourse.User.current();
|
this.controllerFor('navigation/category').setProperties({
|
||||||
this.controllerFor('navigation/category').setProperties(opts);
|
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 || {};
|
params = params || {};
|
||||||
|
|
||||||
if (queryParams && queryParams.order) { params.order = queryParams.order; }
|
if (queryParams && queryParams.order) { params.order = queryParams.order; }
|
||||||
@ -67,6 +90,10 @@ export default function(filter, params) {
|
|||||||
|
|
||||||
renderTemplate: function() {
|
renderTemplate: function() {
|
||||||
this.render('navigation/category', { outlet: 'navigation-bar' });
|
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' });
|
this.render('discovery/topics', { controller: 'discovery/topics', outlet: 'list-container' });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -14,7 +14,16 @@
|
|||||||
<div class='spinner'>{{i18n loading}}</div>
|
<div class='spinner'>{{i18n loading}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div {{bind-attr class=":container :list-container loadingSpinner:hidden"}}>
|
<div {{bind-attr class=":container :list-container loadingSpinner:hidden"}}>
|
||||||
|
<div class="row">
|
||||||
|
<div class="full-width">
|
||||||
|
<div id='header-list-area'>
|
||||||
|
{{outlet header-list-container}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="full-width">
|
<div class="full-width">
|
||||||
<div id='list-area'>
|
<div id='list-area'>
|
||||||
|
@ -20,16 +20,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="pull-left">
|
<div class="pull-left">
|
||||||
{{#if controller.ordering}}<i class="fa fa-bars"></i>{{/if}}
|
{{#if controller.ordering}}<i class="fa fa-bars"></i>{{/if}}
|
||||||
<h3>
|
{{category-title-link category=this}}
|
||||||
{{#if read_restricted}}<i class='fa fa-group'></i>{{/if}}
|
|
||||||
{{#link-to 'discovery.parentCategory' this}}
|
|
||||||
{{#if logo_url}}
|
|
||||||
<img src="{{unbound logo_url}}" class='category-logo'>
|
|
||||||
{{else}}
|
|
||||||
{{unbound name}}
|
|
||||||
{{/if}}
|
|
||||||
{{/link-to}}
|
|
||||||
</h3>
|
|
||||||
{{#if unreadTopics}}
|
{{#if unreadTopics}}
|
||||||
<a href={{unbound unreadUrl}} class='badge new-posts badge-notification' title='{{i18n topic.unread_topics count="unreadTopics"}}'>{{unbound unreadTopics}}</a>
|
<a href={{unbound unreadUrl}} class='badge new-posts badge-notification' title='{{i18n topic.unread_topics count="unreadTopics"}}'>{{unbound unreadTopics}}</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
{{bread-crumbs categories=categories category=category noSubcategories=noSubcategories}}
|
{{bread-crumbs categories=categories
|
||||||
|
category=category
|
||||||
|
noSubcategories=noSubcategories
|
||||||
|
hideSubcategories=showingSubcategoryList}}
|
||||||
|
|
||||||
<ul class="nav nav-pills" id='navigation-bar'>
|
<ul class="nav nav-pills" id='navigation-bar'>
|
||||||
{{#each navItem in navItems}}
|
{{#each navItem in navItems}}
|
||||||
|
@ -11,8 +11,9 @@ class CategoriesController < ApplicationController
|
|||||||
|
|
||||||
options = {}
|
options = {}
|
||||||
options[:latest_posts] = params[:latest_posts] || SiteSetting.category_featured_topics
|
options[:latest_posts] = params[:latest_posts] || SiteSetting.category_featured_topics
|
||||||
|
options[:parent_category_id] = params[:parent_category_id]
|
||||||
|
|
||||||
@list = CategoryList.new(guardian,options)
|
@list = CategoryList.new(guardian, options)
|
||||||
@list.draft_key = Draft::NEW_TOPIC
|
@list.draft_key = Draft::NEW_TOPIC
|
||||||
@list.draft_sequence = DraftSequence.current(current_user, 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
|
@list.draft = Draft.get(current_user, @list.draft_key, @list.draft_sequence) if current_user
|
||||||
|
@ -58,6 +58,10 @@ class CategoryList
|
|||||||
.includes(:featured_users, subcategories: [:topic_only_relative_url])
|
.includes(:featured_users, subcategories: [:topic_only_relative_url])
|
||||||
.secured(@guardian)
|
.secured(@guardian)
|
||||||
|
|
||||||
|
if @options[:parent_category_id].present?
|
||||||
|
@categories = @categories.where('categories.parent_category_id = ?', @options[:parent_category_id].to_i)
|
||||||
|
end
|
||||||
|
|
||||||
if SiteSetting.fixed_category_positions
|
if SiteSetting.fixed_category_positions
|
||||||
@categories = @categories.order('position ASC').order('id ASC')
|
@categories = @categories.order('position ASC').order('id ASC')
|
||||||
else
|
else
|
||||||
@ -72,21 +76,23 @@ class CategoryList
|
|||||||
end
|
end
|
||||||
|
|
||||||
@categories = @categories.to_a
|
@categories = @categories.to_a
|
||||||
subcategories = {}
|
if @options[:parent_category_id].blank?
|
||||||
to_delete = Set.new
|
subcategories = {}
|
||||||
@categories.each do |c|
|
to_delete = Set.new
|
||||||
if c.parent_category_id.present?
|
|
||||||
subcategories[c.parent_category_id] ||= []
|
|
||||||
subcategories[c.parent_category_id] << c.id
|
|
||||||
to_delete << c
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if subcategories.present?
|
|
||||||
@categories.each do |c|
|
@categories.each do |c|
|
||||||
c.subcategory_ids = subcategories[c.id]
|
if c.parent_category_id.present?
|
||||||
|
subcategories[c.parent_category_id] ||= []
|
||||||
|
subcategories[c.parent_category_id] << c.id
|
||||||
|
to_delete << c
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if subcategories.present?
|
||||||
|
@categories.each do |c|
|
||||||
|
c.subcategory_ids = subcategories[c.id]
|
||||||
|
end
|
||||||
|
@categories.delete_if {|c| to_delete.include?(c) }
|
||||||
end
|
end
|
||||||
@categories.delete_if {|c| to_delete.include?(c) }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if latest_post_only?
|
if latest_post_only?
|
||||||
|
Loading…
Reference in New Issue
Block a user