mirror of
https://github.com/discourse/discourse.git
synced 2025-02-16 18:24:52 -06:00
FEATURE: box-style rendering of sub-categories
This commit is contained in:
parent
60dc531531
commit
6d7e968e30
@ -0,0 +1,11 @@
|
||||
import computed from 'ember-addons/ember-computed-decorators';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
tagName: "section",
|
||||
classNameBindings: [':category-boxes', 'anyLogos:with-logos:no-logos'],
|
||||
|
||||
@computed('categories.[].uploaded_logo.url')
|
||||
anyLogos() {
|
||||
return this.get("categories").any((c) => { return !Ember.isEmpty(c.get('uploaded_logo.url')); });
|
||||
}
|
||||
});
|
@ -1,11 +1,10 @@
|
||||
const EditCategoryPanel = Ember.Component.extend({
|
||||
classNameBindings: [':modal-tab', 'activeTab::invisible'],
|
||||
});
|
||||
const EditCategoryPanel = Ember.Component.extend({});
|
||||
|
||||
export default EditCategoryPanel;
|
||||
|
||||
export function buildCategoryPanel(tab, extras) {
|
||||
return EditCategoryPanel.extend({
|
||||
activeTab: Ember.computed.equal('selectedTab', tab)
|
||||
activeTab: Ember.computed.equal('selectedTab', tab),
|
||||
classNameBindings: [':modal-tab', 'activeTab::invisible', `:edit-category-tab-${tab}`]
|
||||
}, extras || {});
|
||||
}
|
||||
|
@ -5,9 +5,27 @@ import computed from "ember-addons/ember-computed-decorators";
|
||||
export default buildCategoryPanel('settings', {
|
||||
emailInEnabled: setting('email_in'),
|
||||
showPositionInput: setting('fixed_category_positions'),
|
||||
|
||||
isParentCategory: Em.computed.empty('category.parent_category_id'),
|
||||
showSubcategoryListStyle: Em.computed.and('category.show_subcategory_list', 'isParentCategory'),
|
||||
isDefaultSortOrder: Em.computed.empty('category.sort_order'),
|
||||
|
||||
@computed
|
||||
availableSubcategoryListStyles() {
|
||||
return [
|
||||
{name: I18n.t('category.subcategory_list_styles.rows'), value: 'rows'},
|
||||
{name: I18n.t('category.subcategory_list_styles.rows_with_featured_topics'), value: 'rows_with_featured_topics'},
|
||||
{name: I18n.t('category.subcategory_list_styles.boxes'), value: 'boxes'}
|
||||
];
|
||||
},
|
||||
|
||||
@computed
|
||||
availableViews() {
|
||||
return [
|
||||
{name: I18n.t('filters.latest.title'), value: 'latest'},
|
||||
{name: I18n.t('filters.top.title'), value: 'top'}
|
||||
];
|
||||
},
|
||||
|
||||
@computed
|
||||
availableSorts() {
|
||||
return ['likes', 'op_likes', 'views', 'posts', 'activity', 'posters', 'category', 'created']
|
||||
@ -21,13 +39,5 @@ export default buildCategoryPanel('settings', {
|
||||
{name: I18n.t('category.sort_ascending'), value: 'true'},
|
||||
{name: I18n.t('category.sort_descending'), value: 'false'}
|
||||
];
|
||||
},
|
||||
|
||||
@computed
|
||||
availableViews() {
|
||||
return [
|
||||
{name: I18n.t('filters.latest.title'), value: 'latest'},
|
||||
{name: I18n.t('filters.top.title'), value: 'top'}
|
||||
];
|
||||
}
|
||||
});
|
||||
|
@ -19,7 +19,22 @@ export default DiscoveryController.extend({
|
||||
|
||||
@computed("model.parentCategory")
|
||||
categoryPageStyle(parentCategory) {
|
||||
const style = this.siteSettings.desktop_category_page_style;
|
||||
let style = this.siteSettings.desktop_category_page_style;
|
||||
|
||||
if (parentCategory) {
|
||||
switch(parentCategory.get('subcategory_list_style')) {
|
||||
case 'rows':
|
||||
style = "categories_only";
|
||||
break;
|
||||
case 'rows_with_featured_topics':
|
||||
style = "categories_with_featured_topics";
|
||||
break;
|
||||
case 'boxes':
|
||||
style = "categories_boxes";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const componentName = (parentCategory && style === "categories_and_latest_topics") ?
|
||||
"categories_only" :
|
||||
style;
|
||||
|
@ -105,7 +105,8 @@ const Category = RestModel.extend({
|
||||
topic_featured_link_allowed: this.get('topic_featured_link_allowed'),
|
||||
show_subcategory_list: this.get('show_subcategory_list'),
|
||||
num_featured_topics: this.get('num_featured_topics'),
|
||||
default_view: this.get('default_view')
|
||||
default_view: this.get('default_view'),
|
||||
subcategory_list_style: this.get('subcategory_list_style')
|
||||
},
|
||||
type: id ? 'PUT' : 'POST'
|
||||
});
|
||||
|
@ -0,0 +1,16 @@
|
||||
{{#if categories}}
|
||||
{{#each categories as |c|}}
|
||||
<div class='category-box'>
|
||||
<a href={{c.url}}>
|
||||
{{cdn-img src=c.uploaded_logo.url class="logo"}}
|
||||
|
||||
<div class='details'>
|
||||
<h3>{{c.name}}</h3>
|
||||
<div class='description'>
|
||||
{{c.description}}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
{{/each}}
|
||||
{{/if}}
|
@ -19,14 +19,51 @@
|
||||
</label>
|
||||
</section>
|
||||
|
||||
{{#unless category.parent_category_id}}
|
||||
<section class="field">
|
||||
{{#if isParentCategory}}
|
||||
<section class="field show-subcategory-list-field">
|
||||
<label>
|
||||
{{input type="checkbox" checked=category.show_subcategory_list}}
|
||||
{{i18n "category.show_subcategory_list"}}
|
||||
</label>
|
||||
</section>
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
|
||||
{{#if showSubcategoryListStyle}}
|
||||
<section class="field subcategory-list-style-field">
|
||||
<label>
|
||||
{{i18n "category.subcategory_list_style"}}
|
||||
{{combo-box valueAttribute="value" content=availableSubcategoryListStyles value=category.subcategory_list_style}}
|
||||
</label>
|
||||
</section>
|
||||
{{/if}}
|
||||
|
||||
<section class="field default-view-field">
|
||||
<label>
|
||||
{{i18n "category.default_view"}}
|
||||
{{combo-box valueAttribute="value" content=availableViews value=category.default_view}}
|
||||
</label>
|
||||
</section>
|
||||
|
||||
<section class="field">
|
||||
<label>
|
||||
{{i18n "category.sort_order"}}
|
||||
{{combo-box valueAttribute="value" content=availableSorts value=category.sort_order none="category.sort_options.default"}}
|
||||
{{#unless isDefaultSortOrder}}
|
||||
{{combo-box valueAttribute="value" content=sortAscendingOptions value=category.sort_ascending none="category.sort_options.default"}}
|
||||
{{/unless}}
|
||||
</label>
|
||||
</section>
|
||||
|
||||
<section class="field num-featured-topics-fields">
|
||||
<label>
|
||||
{{#if category.parent_category_id}}
|
||||
{{i18n "category.subcategory_num_featured_topics"}}
|
||||
{{else}}
|
||||
{{i18n "category.num_featured_topics"}}
|
||||
{{/if}}
|
||||
{{text-field value=category.num_featured_topics}}
|
||||
</label>
|
||||
</section>
|
||||
|
||||
<section class="field">
|
||||
<label>
|
||||
@ -46,23 +83,6 @@
|
||||
</section>
|
||||
{{/if}}
|
||||
|
||||
<section class="field">
|
||||
<label>
|
||||
{{i18n "category.sort_order"}}
|
||||
{{combo-box valueAttribute="value" content=availableSorts value=category.sort_order none="category.sort_options.default"}}
|
||||
{{#unless isDefaultSortOrder}}
|
||||
{{combo-box valueAttribute="value" content=sortAscendingOptions value=category.sort_ascending none="category.sort_options.default"}}
|
||||
{{/unless}}
|
||||
</label>
|
||||
</section>
|
||||
|
||||
<section class="field default-view-field">
|
||||
<label>
|
||||
{{i18n "category.default_view"}}
|
||||
{{combo-box valueAttribute="value" content=availableViews value=category.default_view}}
|
||||
</label>
|
||||
</section>
|
||||
|
||||
{{#if emailInEnabled}}
|
||||
<section class='field'>
|
||||
<label>
|
||||
@ -82,17 +102,6 @@
|
||||
{{plugin-outlet name="category-email-in" args=(hash category=category)}}
|
||||
{{/if}}
|
||||
|
||||
<section class="field num-featured-topics-fields">
|
||||
<label>
|
||||
{{#if category.parent_category_id}}
|
||||
{{i18n "category.subcategory_num_featured_topics"}}
|
||||
{{else}}
|
||||
{{i18n "category.num_featured_topics"}}
|
||||
{{/if}}
|
||||
{{text-field value=category.num_featured_topics}}
|
||||
</label>
|
||||
</section>
|
||||
|
||||
{{#if showPositionInput}}
|
||||
<section class='field position-fields'>
|
||||
<label>
|
||||
|
@ -322,6 +322,16 @@
|
||||
.auto-close-fields label {
|
||||
font-size: .929em;
|
||||
}
|
||||
|
||||
.subcategory-list-style-field {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.edit-category-tab-settings {
|
||||
section.field {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.incoming-email-modal {
|
||||
|
@ -176,3 +176,60 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.category-boxes {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
width: 100%;
|
||||
|
||||
.category-box {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-content: flex-start;
|
||||
|
||||
box-sizing: border-box;
|
||||
width: 23%;
|
||||
padding: 1em;
|
||||
margin: 0 1% 1.5em 1%;
|
||||
border: 2px solid blend-primary-secondary(20%);
|
||||
|
||||
.mobile-view & {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.details {
|
||||
text-align: center;
|
||||
h3 {
|
||||
font-size: 1.5em;
|
||||
margin-bottom: 0.5em;
|
||||
margin-top: 0.25em;
|
||||
}
|
||||
.description {
|
||||
font-size: 1.05em;
|
||||
color: dark-light-choose(scale-color($primary, $lightness: 50%), scale-color($secondary, $lightness: 40%));
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: block;
|
||||
height: 40px;
|
||||
margin: 0 auto 1em auto;
|
||||
}
|
||||
}
|
||||
|
||||
&.no-logos {
|
||||
.logo {
|
||||
display: none;
|
||||
}
|
||||
.category-box {
|
||||
padding: 3em 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,10 +16,12 @@ class CategoriesController < ApplicationController
|
||||
|
||||
@description = SiteSetting.site_description
|
||||
|
||||
parent_category = Category.find_by(slug: params[:parent_category_id]) || Category.find_by(id: params[:parent_category_id].to_i)
|
||||
|
||||
category_options = {
|
||||
is_homepage: current_homepage == "categories".freeze,
|
||||
parent_category_id: params[:parent_category_id],
|
||||
include_topics: include_topics
|
||||
include_topics: include_topics(parent_category)
|
||||
}
|
||||
|
||||
@category_list = CategoryList.new(guardian, category_options)
|
||||
@ -246,6 +248,7 @@ class CategoriesController < ApplicationController
|
||||
:show_subcategory_list,
|
||||
:num_featured_topics,
|
||||
:default_view,
|
||||
:subcategory_list_style,
|
||||
:custom_fields => [params[:custom_fields].try(:keys)],
|
||||
:permissions => [*p.try(:keys)],
|
||||
:allowed_tags => [],
|
||||
@ -261,9 +264,10 @@ class CategoriesController < ApplicationController
|
||||
@staff_action_logger = StaffActionLogger.new(current_user)
|
||||
end
|
||||
|
||||
def include_topics
|
||||
def include_topics(parent_category=nil)
|
||||
view_context.mobile_view? ||
|
||||
params[:include_topics] ||
|
||||
(parent_category && parent_category.subcategory_list_includes_topics?) ||
|
||||
SiteSetting.desktop_category_page_style == "categories_with_featured_topics".freeze
|
||||
end
|
||||
end
|
||||
|
@ -507,6 +507,10 @@ SQL
|
||||
self.where(slug: category_slug, parent_category_id: nil).first
|
||||
end
|
||||
end
|
||||
|
||||
def subcategory_list_includes_topics?
|
||||
subcategory_list_style == 'rows_with_featured_topics'
|
||||
end
|
||||
end
|
||||
|
||||
# == Schema Information
|
||||
|
@ -22,7 +22,8 @@ class BasicCategorySerializer < ApplicationSerializer
|
||||
:sort_ascending,
|
||||
:show_subcategory_list,
|
||||
:num_featured_topics,
|
||||
:default_view
|
||||
:default_view,
|
||||
:subcategory_list_style
|
||||
|
||||
has_one :uploaded_logo, embed: :object, serializer: CategoryUploadSerializer
|
||||
has_one :uploaded_background, embed: :object, serializer: CategoryUploadSerializer
|
||||
|
@ -1987,8 +1987,9 @@ en:
|
||||
num_featured_topics: "Number of topics shown on the categories page:"
|
||||
subcategory_num_featured_topics: "Number of featured topics on parent category's page:"
|
||||
all_topics_wiki: "Make new topics wikis by default."
|
||||
sort_order: "Default Sort:"
|
||||
default_view: "Default View:"
|
||||
subcategory_list_style: "Subcategory List Style:"
|
||||
sort_order: "Topic List Sort By:"
|
||||
default_view: "Default Topic List:"
|
||||
allow_badges_label: "Allow badges to be awarded in this category"
|
||||
edit_permissions: "Edit Permissions"
|
||||
add_permission: "Add Permission"
|
||||
@ -2026,6 +2027,10 @@ en:
|
||||
created: "Created"
|
||||
sort_ascending: 'Ascending'
|
||||
sort_descending: 'Descending'
|
||||
subcategory_list_styles:
|
||||
rows: "Rows"
|
||||
rows_with_featured_topics: "Rows with featured topics"
|
||||
boxes: "Boxes"
|
||||
|
||||
flagging:
|
||||
title: 'Thanks for helping to keep our community civil!'
|
||||
|
@ -0,0 +1,14 @@
|
||||
class AddSubcategoryListStyleToCategories < ActiveRecord::Migration
|
||||
def up
|
||||
add_column :categories, :subcategory_list_style, :string, limit: 50, default: 'rows_with_featured_topics'
|
||||
|
||||
result = execute("select value from site_settings where name = 'desktop_category_page_style' and value != 'categories_with_featured_topics'")
|
||||
if result.count > 0
|
||||
execute "UPDATE categories SET subcategory_list_style = 'rows' WHERE parent_category_id IS NULL"
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
remove_column :categories, :subcategory_list_style
|
||||
end
|
||||
end
|
@ -57,3 +57,28 @@ test("Error Saving", assert => {
|
||||
assert.equal(find('#modal-alert').html(), "duplicate email");
|
||||
});
|
||||
});
|
||||
|
||||
test("Subcategory list settings", () => {
|
||||
visit("/c/bug");
|
||||
|
||||
click('.edit-category');
|
||||
click('.edit-category-settings');
|
||||
|
||||
andThen(() => {
|
||||
ok(!visible(".subcategory-list-style-field"), "subcategory list style isn't visible by default");
|
||||
});
|
||||
|
||||
click(".show-subcategory-list-field input[type=checkbox]");
|
||||
andThen(() => {
|
||||
ok(visible(".subcategory-list-style-field"), "subcategory list style is shown if show subcategory list is checked");
|
||||
});
|
||||
|
||||
click('.edit-category-general');
|
||||
selectDropdown('.edit-category-tab-general .category-combobox', 2);
|
||||
|
||||
click('.edit-category-settings');
|
||||
andThen(() => {
|
||||
ok(!visible(".show-subcategory-list-field"), "show subcategory list isn't visible for child categories");
|
||||
ok(!visible(".subcategory-list-style-field"), "subcategory list style isn't visible for child categories");
|
||||
});
|
||||
});
|
||||
|
@ -13,6 +13,7 @@ test("Visit Discovery Pages", () => {
|
||||
andThen(() => {
|
||||
ok(exists(".topic-list"), "The list of topics was rendered");
|
||||
ok(exists('.topic-list .topic-list-item'), "has topics");
|
||||
ok(!exists('.category-list'), "doesn't render subcategories");
|
||||
ok($('body.category-bug').length, "has a custom css class for the category id on the body");
|
||||
});
|
||||
|
||||
@ -29,4 +30,10 @@ test("Visit Discovery Pages", () => {
|
||||
ok($('body.categories-list').length === 0, "removes the `categories-list` class");
|
||||
ok(exists('.topic-list .topic-list-item'), "has topics");
|
||||
});
|
||||
|
||||
visit("/c/feature");
|
||||
andThen(() => {
|
||||
ok(exists(".topic-list"), "The list of topics was rendered");
|
||||
ok(exists(".category-boxes"), "The list of subcategories were rendered with box style");
|
||||
});
|
||||
});
|
||||
|
File diff suppressed because one or more lines are too long
@ -92,7 +92,9 @@ export default {
|
||||
"permission":1,
|
||||
"notification_level":null,
|
||||
"logo_url":null,
|
||||
"background_url":null
|
||||
"background_url":null,
|
||||
"show_subcategory_list":false,
|
||||
"default_view":"latest"
|
||||
},
|
||||
{
|
||||
"id":10,
|
||||
@ -108,7 +110,9 @@ export default {
|
||||
"permission":1,
|
||||
"notification_level":null,
|
||||
"logo_url":null,
|
||||
"background_url":null
|
||||
"background_url":null,
|
||||
"show_subcategory_list":false,
|
||||
"default_view":"latest"
|
||||
},
|
||||
{
|
||||
"id":26,
|
||||
@ -141,7 +145,9 @@ export default {
|
||||
"permission":1,
|
||||
"notification_level":null,
|
||||
"logo_url":null,
|
||||
"background_url":null
|
||||
"background_url":null,
|
||||
"show_subcategory_list":false,
|
||||
"default_view":"latest"
|
||||
},
|
||||
{
|
||||
"id":6,
|
||||
@ -157,7 +163,9 @@ export default {
|
||||
"permission":1,
|
||||
"notification_level":null,
|
||||
"logo_url":null,
|
||||
"background_url":null
|
||||
"background_url":null,
|
||||
"show_subcategory_list":false,
|
||||
"default_view":"latest"
|
||||
},
|
||||
{
|
||||
"id":24,
|
||||
@ -224,7 +232,9 @@ export default {
|
||||
"permission":1,
|
||||
"notification_level":null,
|
||||
"logo_url":null,
|
||||
"background_url":null
|
||||
"background_url":null,
|
||||
"show_subcategory_list":false,
|
||||
"default_view":"latest"
|
||||
},
|
||||
{
|
||||
"id":14,
|
||||
@ -240,7 +250,9 @@ export default {
|
||||
"permission":1,
|
||||
"notification_level":null,
|
||||
"logo_url":null,
|
||||
"background_url":null
|
||||
"background_url":null,
|
||||
"show_subcategory_list":false,
|
||||
"default_view":"latest"
|
||||
},
|
||||
{
|
||||
"id":12,
|
||||
@ -256,7 +268,9 @@ export default {
|
||||
"permission":1,
|
||||
"notification_level":null,
|
||||
"logo_url":null,
|
||||
"background_url":null
|
||||
"background_url":null,
|
||||
"show_subcategory_list":false,
|
||||
"default_view":"latest"
|
||||
},
|
||||
{
|
||||
"id":13,
|
||||
@ -272,7 +286,9 @@ export default {
|
||||
"permission":1,
|
||||
"notification_level":null,
|
||||
"logo_url":null,
|
||||
"background_url":null
|
||||
"background_url":null,
|
||||
"show_subcategory_list":false,
|
||||
"default_view":"latest"
|
||||
},
|
||||
{
|
||||
"id":5,
|
||||
@ -288,7 +304,9 @@ export default {
|
||||
"permission":1,
|
||||
"notification_level":null,
|
||||
"logo_url":null,
|
||||
"background_url":null
|
||||
"background_url":null,
|
||||
"show_subcategory_list":false,
|
||||
"default_view":"latest"
|
||||
},
|
||||
{
|
||||
"id":11,
|
||||
@ -304,7 +322,9 @@ export default {
|
||||
"permission":1,
|
||||
"notification_level":null,
|
||||
"logo_url":null,
|
||||
"background_url":null
|
||||
"background_url":null,
|
||||
"show_subcategory_list":false,
|
||||
"default_view":"latest"
|
||||
},
|
||||
{
|
||||
"id":22,
|
||||
@ -338,7 +358,9 @@ export default {
|
||||
"notification_level":null,
|
||||
"logo_url":null,
|
||||
"background_url":null,
|
||||
"can_edit":true
|
||||
"can_edit":true,
|
||||
"show_subcategory_list":false,
|
||||
"default_view":"latest"
|
||||
},
|
||||
{
|
||||
"id":17,
|
||||
@ -354,7 +376,9 @@ export default {
|
||||
"permission":1,
|
||||
"notification_level":null,
|
||||
"logo_url":"",
|
||||
"background_url":""
|
||||
"background_url":"",
|
||||
"show_subcategory_list":false,
|
||||
"default_view":"latest"
|
||||
},
|
||||
{
|
||||
"id":21,
|
||||
@ -387,7 +411,9 @@ export default {
|
||||
"permission":1,
|
||||
"notification_level":null,
|
||||
"logo_url":null,
|
||||
"background_url":null
|
||||
"background_url":null,
|
||||
"show_subcategory_list":false,
|
||||
"default_view":"latest"
|
||||
},
|
||||
{
|
||||
"id":9,
|
||||
@ -403,7 +429,9 @@ export default {
|
||||
"permission":1,
|
||||
"notification_level":null,
|
||||
"logo_url":null,
|
||||
"background_url":null
|
||||
"background_url":null,
|
||||
"show_subcategory_list":false,
|
||||
"default_view":"latest"
|
||||
},
|
||||
{
|
||||
"id":2,
|
||||
@ -419,7 +447,10 @@ export default {
|
||||
"permission":1,
|
||||
"notification_level":null,
|
||||
"logo_url":null,
|
||||
"background_url":null
|
||||
"background_url":null,
|
||||
"show_subcategory_list":true,
|
||||
"default_view":"latest",
|
||||
"subcategory_list_style":"boxes"
|
||||
}
|
||||
],
|
||||
"post_action_types":[
|
||||
|
Loading…
Reference in New Issue
Block a user