FEATURE: box-style rendering of sub-categories

This commit is contained in:
Neil Lalonde 2017-03-08 11:31:30 -05:00
parent 60dc531531
commit 6d7e968e30
18 changed files with 286 additions and 66 deletions

View File

@ -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')); });
}
});

View File

@ -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 || {});
}

View File

@ -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'}
];
}
});

View File

@ -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;

View File

@ -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'
});

View File

@ -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}}

View File

@ -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>

View File

@ -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 {

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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!'

View File

@ -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

View File

@ -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");
});
});

View File

@ -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

View File

@ -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":[