UX: Change category badge style to use stripes

This commit is contained in:
Robin Ward 2015-01-20 11:36:28 -05:00
parent f3c9310e12
commit 350554e198
27 changed files with 175 additions and 211 deletions

View File

@ -1,11 +1,5 @@
/** var get = Ember.get;
Renders a drop down for selecting a category
@class CategoryDropComponent
@extends Ember.Component
@namespace Discourse
@module Discourse
**/
export default Ember.Component.extend({ export default Ember.Component.extend({
classNameBindings: ['category::no-category', 'categories:has-drop'], classNameBindings: ['category::no-category', 'categories:has-drop'],
tagName: 'li', tagName: 'li',
@ -44,11 +38,20 @@ export default Ember.Component.extend({
badgeStyle: function() { badgeStyle: function() {
var category = this.get('category'); var category = this.get('category');
if (category) { if (category) {
return Discourse.HTML.categoryStyle(category); var color = get(category, 'color'),
} else { textColor = get(category, 'text_color');
return "background-color: #eee; color: #333";
if (color || textColor) {
var style = "";
if (color) { style += "background-color: #" + color + "; "; }
if (textColor) { style += "color: #" + textColor + "; "; }
return style;
}
} }
return "background-color: #eee; color: #333";
}.property('category'), }.property('category'),
clickEventName: function() { clickEventName: function() {

View File

@ -1,3 +1,5 @@
import { categoryBadgeHTML } from 'discourse/helpers/category-link';
export default Ember.Component.extend({ export default Ember.Component.extend({
_initializeAutocomplete: function(){ _initializeAutocomplete: function(){
@ -25,7 +27,7 @@ export default Ember.Component.extend({
}, },
template: template, template: template,
transformComplete: function(category) { transformComplete: function(category) {
return Discourse.HTML.categoryBadge(category, {allowUncategorized: true}); return categoryBadgeHTML(category, {allowUncategorized: true});
} }
}); });
}.on('didInsertElement') }.on('didInsertElement')

View File

@ -1,5 +1,6 @@
import ModalFunctionality from 'discourse/mixins/modal-functionality'; import ModalFunctionality from 'discourse/mixins/modal-functionality';
import ObjectController from 'discourse/controllers/object'; import ObjectController from 'discourse/controllers/object';
import { categoryBadgeHTML } from 'discourse/helpers/category-link';
// Modal for editing / creating a category // Modal for editing / creating a category
export default ObjectController.extend(ModalFunctionality, { export default ObjectController.extend(ModalFunctionality, {
@ -69,7 +70,7 @@ export default ObjectController.extend(ModalFunctionality, {
parent_category_id: parseInt(this.get('parent_category_id'),10), parent_category_id: parseInt(this.get('parent_category_id'),10),
read_restricted: this.get('model.read_restricted') read_restricted: this.get('model.read_restricted')
}); });
return Discourse.HTML.categoryBadge(c, {showParent: true, link: false}); return categoryBadgeHTML(c, {link: false});
}.property('parent_category_id', 'categoryName', 'color', 'text_color'), }.property('parent_category_id', 'categoryName', 'color', 'text_color'),
// background colors are available as a pipe-separated string // background colors are available as a pipe-separated string

View File

@ -1,5 +1,6 @@
import ModalFunctionality from 'discourse/mixins/modal-functionality'; import ModalFunctionality from 'discourse/mixins/modal-functionality';
import ObjectController from 'discourse/controllers/object'; import ObjectController from 'discourse/controllers/object';
import { categoryBadgeHTML } from 'discourse/helpers/category-link';
// This controller handles displaying of history // This controller handles displaying of history
export default ObjectController.extend(ModalFunctionality, { export default ObjectController.extend(ModalFunctionality, {
@ -22,14 +23,14 @@ export default ObjectController.extend(ModalFunctionality, {
hide: function(postId, postVersion) { hide: function(postId, postVersion) {
var self = this; var self = this;
Discourse.Post.hideRevision(postId, postVersion).then(function (result) { Discourse.Post.hideRevision(postId, postVersion).then(function () {
self.refresh(postId, postVersion); self.refresh(postId, postVersion);
}); });
}, },
show: function(postId, postVersion) { show: function(postId, postVersion) {
var self = this; var self = this;
Discourse.Post.showRevision(postId, postVersion).then(function (result) { Discourse.Post.showRevision(postId, postVersion).then(function () {
self.refresh(postId, postVersion); self.refresh(postId, postVersion);
}); });
}, },
@ -68,7 +69,7 @@ export default ObjectController.extend(ModalFunctionality, {
var changes = this.get("category_changes"); var changes = this.get("category_changes");
if (changes) { if (changes) {
var category = Discourse.Category.findById(changes["previous"]); var category = Discourse.Category.findById(changes["previous"]);
return Discourse.HTML.categoryBadge(category, { allowUncategorized: true }); return categoryBadgeHTML(category, { allowUncategorized: true });
} }
}.property("category_changes"), }.property("category_changes"),
@ -76,12 +77,12 @@ export default ObjectController.extend(ModalFunctionality, {
var changes = this.get("category_changes"); var changes = this.get("category_changes");
if (changes) { if (changes) {
var category = Discourse.Category.findById(changes["current"]); var category = Discourse.Category.findById(changes["current"]);
return Discourse.HTML.categoryBadge(category, { allowUncategorized: true }); return categoryBadgeHTML(category, { allowUncategorized: true });
} }
}.property("category_changes"), }.property("category_changes"),
wiki_diff: function() { wiki_diff: function() {
var changes = this.get("wiki_changes") var changes = this.get("wiki_changes");
if (changes) { if (changes) {
return changes["current"] ? return changes["current"] ?
'<span class="fa-stack"><i class="fa fa-pencil-square-o fa-stack-2x"></i></span>' : '<span class="fa-stack"><i class="fa fa-pencil-square-o fa-stack-2x"></i></span>' :
@ -93,7 +94,7 @@ export default ObjectController.extend(ModalFunctionality, {
var moderator = Discourse.Site.currentProp('post_types.moderator_action'); var moderator = Discourse.Site.currentProp('post_types.moderator_action');
var changes = this.get("post_type_changes"); var changes = this.get("post_type_changes");
if (changes) { if (changes) {
return changes["current"] == moderator ? return changes["current"] === moderator ?
'<span class="fa-stack"><i class="fa fa-shield fa-stack-2x"></i></span>' : '<span class="fa-stack"><i class="fa fa-shield fa-stack-2x"></i></span>' :
'<span class="fa-stack"><i class="fa fa-shield fa-stack-2x"></i><i class="fa fa-ban fa-stack-2x"></i></span>'; '<span class="fa-stack"><i class="fa fa-shield fa-stack-2x"></i><i class="fa fa-ban fa-stack-2x"></i></span>';
} }

View File

@ -1,4 +1,63 @@
import registerUnbound from 'discourse/helpers/register-unbound'; import registerUnbound from 'discourse/helpers/register-unbound';
import { iconHTML } from 'discourse/helpers/fa-icon';
var get = Em.get,
escapeExpression = Handlebars.Utils.escapeExpression;
function categoryStripe(tagName, category, extraClasses, href) {
if (!category) { return ""; }
var color = Em.get(category, 'color'),
style = color ? "style='background-color: #" + color + ";'" : "";
return "<" + tagName + " class='badge-category-parent" + extraClasses + "' " + style + " href=\"" + href + "\"></" + tagName + ">";
}
export function categoryBadgeHTML(category, opts) {
opts = opts || {};
if ((!category) ||
(!opts.allowUncategorized &&
Em.get(category, 'id') === Discourse.Site.currentProp("uncategorized_category_id") &&
Discourse.SiteSettings.suppress_uncategorized_badge
)
) return "";
var description = get(category, 'description_text'),
restricted = get(category, 'read_restricted'),
url = Discourse.getURL("/c/") + Discourse.Category.slugFor(category),
href = (opts.link === false ? '' : url),
tagName = (opts.link === false || opts.link === "false" ? 'span' : 'a'),
extraClasses = (opts.extraClasses ? (' ' + opts.extraClasses) : '');
var html = "";
var parentCat = Discourse.Category.findById(category.get('parent_category_id'));
if (opts.hideParent) { parentCat = null; }
html += categoryStripe(tagName, parentCat, extraClasses, href);
if (parentCat !== category) {
html += categoryStripe(tagName, category, extraClasses, href);
}
var classNames = "badge-category clear-badge" + extraClasses;
if (restricted) { classNames += " restricted"; }
html += "<" + tagName + ' href="' + href + '" ' +
'data-drop-close="true" class="' + classNames + '"' +
(description ? 'title="' + escapeExpression(description) + '" ' : '') +
">";
var name = escapeExpression(get(category, 'name'));
if (restricted) {
html += "<div>" + iconHTML('lock') + " " + name + "</div>";
} else {
html += name;
}
html += "</" + tagName + ">";
return "<span class='badge-wrapper'>" + html + "</span>";
}
export function categoryLinkHTML(category, options) { export function categoryLinkHTML(category, options) {
var categoryOptions = {}; var categoryOptions = {};
@ -9,12 +68,11 @@ export function categoryLinkHTML(category, options) {
if (options) { if (options) {
if (options.allowUncategorized) { categoryOptions.allowUncategorized = true; } if (options.allowUncategorized) { categoryOptions.allowUncategorized = true; }
if (options.showParent) { categoryOptions.showParent = true; }
if (options.onlyStripe) { categoryOptions.onlyStripe = true; }
if (options.link !== undefined) { categoryOptions.link = options.link; } if (options.link !== undefined) { categoryOptions.link = options.link; }
if (options.extraClasses) { categoryOptions.extraClasses = options.extraClasses; } if (options.extraClasses) { categoryOptions.extraClasses = options.extraClasses; }
if (options.hideParent) { categoryOptions.hideParent = true; }
} }
return new Handlebars.SafeString(Discourse.HTML.categoryBadge(category, categoryOptions)); return new Handlebars.SafeString(categoryBadgeHTML(category, categoryOptions));
} }
registerUnbound('category-link', categoryLinkHTML); registerUnbound('category-link', categoryLinkHTML);

View File

@ -1,11 +1,3 @@
/**
Helpers to build HTML strings as well as custom fragments.
@class HTML
@namespace Discourse
@module Discourse
**/
var customizations = {}; var customizations = {};
Discourse.HTML = { Discourse.HTML = {
@ -15,9 +7,6 @@ Discourse.HTML = {
using `setCustomHTML(key, html)`. This is used by a handlebars helper to find using `setCustomHTML(key, html)`. This is used by a handlebars helper to find
the HTML content it wants. It will also check the `PreloadStore` for any server the HTML content it wants. It will also check the `PreloadStore` for any server
side preloaded HTML. side preloaded HTML.
@method getCustomHTML
@param {String} key to lookup
**/ **/
getCustomHTML: function(key) { getCustomHTML: function(key) {
var c = customizations[key]; var c = customizations[key];
@ -31,104 +20,9 @@ Discourse.HTML = {
} }
}, },
/** // Set a fragment of HTML by key. It can then be looked up with `getCustomHTML(key)`.
Set a fragment of HTML by key. It can then be looked up with `getCustomHTML(key)`.
@method setCustomHTML
@param {String} key to store the html
@param {String} html fragment to store
**/
setCustomHTML: function(key, html) { setCustomHTML: function(key, html) {
customizations[key] = html; customizations[key] = html;
},
/**
Returns the CSS styles for a category
@method categoryStyle
@param {Discourse.Category} category the category whose link we want
**/
categoryStyle: function(category) {
var color = Em.get(category, 'color'),
textColor = Em.get(category, 'text_color');
if (!color && !textColor) { return; }
// Add the custom style if we need to
var style = "";
if (color) { style += "background-color: #" + color + "; "; }
if (textColor) { style += "color: #" + textColor + "; "; }
return style;
},
/**
Create a category badge
@method categoryBadge
@param {Discourse.Category} category the category whose link we want
@param {Object} opts The options for the category link
@param {Boolean} opts.allowUncategorized Whether we allow rendering of the uncategorized category (default false)
@param {Boolean} opts.showParent Whether to visually show whether category is a sub-category (default false)
@param {Boolean} opts.link Whether this category badge should link to the category (default true)
@param {String} opts.extraClasses add this string to the class attribute of the badge
@returns {String} the html category badge
**/
categoryBadge: function(category, opts) {
opts = opts || {};
if ((!category) ||
(!opts.allowUncategorized &&
Em.get(category, 'id') === Discourse.Site.currentProp("uncategorized_category_id") &&
Discourse.SiteSettings.suppress_uncategorized_badge
)
) return "";
var name = Em.get(category, 'name'),
description = Em.get(category, 'description_text'),
restricted = Em.get(category, 'read_restricted'),
url = Discourse.getURL("/c/") + Discourse.Category.slugFor(category),
elem = (opts.link === false ? 'span' : 'a'),
extraClasses = (opts.extraClasses ? (' ' + opts.extraClasses) : ''),
html = "<" + elem + " href=\"" + (opts.link === false ? '' : url) + "\" ",
categoryStyle;
// Parent stripe implies onlyStripe
if (opts.onlyStripe) { opts.showParent = true; }
html += "data-drop-close=\"true\" class=\"badge-category" + (restricted ? ' restricted' : '' ) +
(opts.onlyStripe ? ' clear-badge' : '') +
extraClasses + "\" ";
name = Handlebars.Utils.escapeExpression(name);
// Add description if we have it, without tags. Server has sanitized the description value.
if (description) html += "title=\"" + Handlebars.Utils.escapeExpression(description) + "\" ";
if (!opts.onlyStripe) {
categoryStyle = Discourse.HTML.categoryStyle(category);
if (categoryStyle) {
html += "style=\"" + categoryStyle + "\" ";
}
}
if (restricted) {
html += "><div><i class='fa fa-lock'></i> " + name + "</div></" + elem + ">";
} else {
html += ">" + name + "</" + elem + ">";
}
if (opts.onlyStripe || (opts.showParent && category.get('parent_category_id'))) {
var parent = Discourse.Category.findById(category.get('parent_category_id'));
if (!parent) { parent = category; }
categoryStyle = Discourse.HTML.categoryStyle(opts.onlyStripe ? category : parent) || '';
html = "<span class='badge-wrapper'><" + elem + " class='badge-category-parent" + extraClasses + "' style=\"" + categoryStyle +
"\" href=\"" + (opts.link === false ? '' : url) + "\"><span class='category-name'>" +
(Em.get(parent, 'read_restricted') ? "<i class='fa fa-lock'></i> " : "") +
Em.get(parent, 'name') + "</span></" + elem + ">" +
html + "</span>";
}
return html;
} }
}; };

View File

@ -232,6 +232,7 @@ Discourse.Category.reopenClass({
}, },
findById: function(id) { findById: function(id) {
if (!id) { return; }
return Discourse.Category.idMap()[id]; return Discourse.Category.idMap()[id];
}, },

View File

@ -1,7 +1,7 @@
<div class='autocomplete'> <div class='autocomplete'>
<ul> <ul>
{{#each option in options}} {{#each option in options}}
<li>{{category-link option allowUncategorized="true"}}</li> <li>{{category-link option allowUncategorized="true" link="false"}}</li>
{{/each}} {{/each}}
</ul> </ul>
</div> </div>

View File

@ -1,27 +1,27 @@
{{#if category}} {{#if category}}
<a href="#" {{action "expand"}} class="badge-category" {{bind-attr style="badgeStyle"}}> <a href {{action "expand"}} class="badge-category" {{bind-attr style="badgeStyle"}}>
{{#if category.read_restricted}} {{#if category.read_restricted}}
<i class='fa fa-lock'></i> {{fa-icon "lock"}}
{{/if}} {{/if}}
{{category.name}} {{category.name}}
</a> </a>
{{else}} {{else}}
{{#if noSubcategories}} {{#if noSubcategories}}
<a href='#' {{action "expand"}} class='badge-category home' {{bind-attr style="badgeStyle"}}>{{i18n 'categories.no_subcategory'}}</a> <a href {{action "expand"}} class='badge-category home' {{bind-attr style="badgeStyle"}}>{{i18n 'categories.no_subcategory'}}</a>
{{else}} {{else}}
<a href='#' {{action "expand"}} class='badge-category home' {{bind-attr style="badgeStyle"}}>{{allCategoriesLabel}}</a> <a href {{action "expand"}} class='badge-category home' {{bind-attr style="badgeStyle"}}>{{allCategoriesLabel}}</a>
{{/if}} {{/if}}
{{/if}} {{/if}}
{{#if categories}} {{#if categories}}
<a href='#' {{action "expand"}} {{bind-attr class="dropdownButtonClass" style="badgeStyle"}}><i {{bind-attr class="iconClass"}}></i></a> <a href {{action "expand"}} {{bind-attr class="dropdownButtonClass" style="badgeStyle"}}><i {{bind-attr class="iconClass"}}></i></a>
<section {{bind-attr class="expanded::hidden :category-dropdown-menu"}} class='chooser'> <section {{bind-attr class="expanded::hidden :category-dropdown-menu"}} class='chooser'>
<div class='cat'><a {{bind-attr href=allCategoriesUrl}} data-drop-close="true" class='badge-category home'>{{allCategoriesLabel}}</a></div> <div class='cat'><a {{bind-attr href=allCategoriesUrl}} data-drop-close="true" class='badge-category home'>{{allCategoriesLabel}}</a></div>
{{#if subCategory}} {{#if subCategory}}
<div class='cat'><a {{bind-attr href=noCategoriesUrl}} data-drop-close="true" class='badge-category home'>{{i18n 'categories.no_subcategory'}}</a></div> <div class='cat'><a {{bind-attr href=noCategoriesUrl}} data-drop-close="true" class='badge-category home'>{{i18n 'categories.no_subcategory'}}</a></div>
{{/if}} {{/if}}
{{#if renderCategories}} {{#if renderCategories}}
{{#each c in categories}}<div class='cat'>{{category-link c allowUncategorized=true}}</div>{{/each}} {{#each c in categories}}<div class='cat'>{{category-link c allowUncategorized=true hideParent=subCategory}}</div>{{/each}}
{{/if}} {{/if}}
</section> </section>
{{/if}} {{/if}}

View File

@ -32,7 +32,7 @@
{{#if c.subcategories}} {{#if c.subcategories}}
<div class='subcategories'> <div class='subcategories'>
{{#each s in c.subcategories}} {{#each s in c.subcategories}}
{{category-link s showParent="true" onlyStripe="true"}} {{category-link s hideParent="true"}}
{{#if s.unreadTopics}} {{#if s.unreadTopics}}
<a href={{unbound s.unreadUrl}} class='badge new-posts badge-notification' title='{{i18n 'topic.unread_topics' count=s.unreadTopics}}'>{{unbound s.unreadTopics}}</a> <a href={{unbound s.unreadUrl}} class='badge new-posts badge-notification' title='{{i18n 'topic.unread_topics' count=s.unreadTopics}}'>{{unbound s.unreadTopics}}</a>
{{/if}} {{/if}}

View File

@ -113,9 +113,9 @@
{{/if}} {{/if}}
</h1> </h1>
{{#if topic.category.parentCategory}} {{#if topic.category.parentCategory}}
{{bound-category-link topic.category.parentCategory onlyStripe="true"}} {{bound-category-link topic.category.parentCategory}}
{{/if}} {{/if}}
{{bound-category-link topic.category onlyStripe="true"}} {{bound-category-link topic.category hideParent=true}}
</div> </div>
</div> </div>
</div> </div>

View File

@ -1 +1 @@
<td class='category'>{{category-link category showParent="true"}}</td> <td class='category'>{{category-link category}}</td>

View File

@ -32,7 +32,7 @@
</div> </div>
{{#unless controller.hideCategory}} {{#unless controller.hideCategory}}
<div class='category'> <div class='category'>
{{category-link t.category showParent="true"}} {{category-link t.category}}
</div> </div>
{{/unless}} {{/unless}}
{{#if controller.showParticipants}} {{#if controller.showParticipants}}

View File

@ -46,7 +46,7 @@
<td> <td>
<div class='subcategories'> <div class='subcategories'>
{{#each subcategory in c.subcategories}} {{#each subcategory in c.subcategories}}
{{category-link subcategory showParent="true"}} {{category-link subcategory}}
{{/each}} {{/each}}
</div> </div>
</td> </td>

View File

@ -11,7 +11,7 @@
<div class="topic-item-stats clearfix"> <div class="topic-item-stats clearfix">
{{#unless controller.hideCategory}} {{#unless controller.hideCategory}}
<div class='category'> <div class='category'>
{{category-link content.category showParent="true"}} {{category-link content.category}}
</div> </div>
{{/unless}} {{/unless}}

View File

@ -15,7 +15,7 @@
{{#if subCategories}} {{#if subCategories}}
<label>{{i18n 'categories.subcategories'}}</label> <label>{{i18n 'categories.subcategories'}}</label>
{{#each s in subCategories}} {{#each s in subCategories}}
{{category-badge s}} {{category-badge s hideParent="true"}}
{{/each}} {{/each}}
{{else}} {{else}}
<label>{{i18n 'category.parent'}}</label> <label>{{i18n 'category.parent'}}</label>

View File

@ -46,7 +46,7 @@
{{#each c in categories itemController='site-map-category'}} {{#each c in categories itemController='site-map-category'}}
<li class="category"> <li class="category">
{{category-link c allowUncategorized="true" showParent="true"}} {{category-link c allowUncategorized="true"}}
{{#if c.unreadTotal}} {{#if c.unreadTotal}}
<a href={{unbound c.url}} class='badge badge-notification'>{{c.unreadTotal}}</a> <a href={{unbound c.url}} class='badge badge-notification'>{{c.unreadTotal}}</a>

View File

@ -46,7 +46,7 @@
{{#if category.parentCategory}} {{#if category.parentCategory}}
{{bound-category-link category.parentCategory}} {{bound-category-link category.parentCategory}}
{{/if}} {{/if}}
{{bound-category-link category}} {{bound-category-link category hideParent=true}}
{{plugin-outlet "topic-category"}} {{plugin-outlet "topic-category"}}
{{/unless}} {{/unless}}
{{/if}} {{/if}}

View File

@ -1,6 +1,5 @@
import ComboboxView from 'discourse/views/combo-box'; import ComboboxView from 'discourse/views/combo-box';
import { categoryBadgeHTML } from 'discourse/helpers/category-link';
var badgeHtml = Discourse.HTML.categoryBadge;
export default ComboboxView.extend({ export default ComboboxView.extend({
classNames: ['combobox category-combobox'], classNames: ['combobox category-combobox'],
@ -57,10 +56,10 @@ export default ComboboxView.extend({
} }
if (!category) return item.text; if (!category) return item.text;
var result = badgeHtml(category, {showParent: false, link: false, allowUncategorized: true}), var result = categoryBadgeHTML(category, {link: false, allowUncategorized: true, hideParent: true}),
parentCategoryId = category.get('parent_category_id'); parentCategoryId = category.get('parent_category_id');
if (parentCategoryId) { if (parentCategoryId) {
result = badgeHtml(Discourse.Category.findById(parentCategoryId), {link: false}) + "&nbsp;" + result; result = categoryBadgeHTML(Discourse.Category.findById(parentCategoryId), {link: false}) + "&nbsp;" + result;
} }
result += " <span class='topic-count'>&times; " + category.get('topic_count') + "</span>"; result += " <span class='topic-count'>&times; " + category.get('topic_count') + "</span>";

View File

@ -1,5 +1,6 @@
import AddCategoryClass from 'discourse/mixins/add-category-class'; import AddCategoryClass from 'discourse/mixins/add-category-class';
import { listenForViewEvent } from 'discourse/lib/app-events'; import { listenForViewEvent } from 'discourse/lib/app-events';
import { categoryBadgeHTML } from 'discourse/helpers/category-link';
var TopicView = Discourse.View.extend(AddCategoryClass, Discourse.Scrolling, { var TopicView = Discourse.View.extend(AddCategoryClass, Discourse.Scrolling, {
templateName: 'topic', templateName: 'topic',
@ -130,7 +131,7 @@ var TopicView = Discourse.View.extend(AddCategoryClass, Discourse.Scrolling, {
} }
if (category) { if (category) {
opts.catLink = Discourse.HTML.categoryBadge(category, {showParent: true}); opts.catLink = categoryBadgeHTML(category);
} else { } else {
opts.catLink = "<a href=\"" + Discourse.getURL("/categories") + "\">" + I18n.t("topic.browse_all_categories") + "</a>"; opts.catLink = "<a href=\"" + Discourse.getURL("/categories") + "\">" + I18n.t("topic.browse_all_categories") + "</a>";
} }

View File

@ -154,9 +154,9 @@
} }
.list-controls { .list-controls {
.home { .category-dropdown-menu .home {
background-color: scale-color-diff();
color: $primary; color: $primary;
margin-left: 8px;
} }
.badge-category { .badge-category {
padding: 4px 10px; padding: 4px 10px;
@ -164,6 +164,10 @@
line-height: 24px; line-height: 24px;
float: left; float: left;
} }
.category-dropdown-menu .badge-category {
width: 100%;
}
.category-dropdown-button { .category-dropdown-button {
border-left: 1px solid rgba(0,0,0,0.15); border-left: 1px solid rgba(0,0,0,0.15);
font-size: 1.143em; font-size: 1.143em;
@ -223,18 +227,21 @@ ol.category-breadcrumb {
background-color: $secondary; background-color: $secondary;
z-index: 100; z-index: 100;
.cat {
margin-right: 20px;
}
a.badge-category, a.badge-category-parent {
line-height: 19px;
overflow:hidden;
margin-bottom: 0;
}
a.badge-category { a.badge-category {
font-size: 0.929em; font-size: 0.929em;
font-weight: bold; font-weight: bold;
float: none; float: none;
line-height: 19px;
text-transform: none; text-transform: none;
width: 100%;
min-width: 102px;
margin-right: 20px;
margin-bottom: 0;
max-width:200px; max-width:200px;
overflow:hidden;
text-overflow:ellipsis; text-overflow:ellipsis;
} }
} }

View File

@ -28,9 +28,9 @@
.badge-category { .badge-category {
padding: 6px; padding: 6px;
color: $secondary; color: $primary;
&[href] { &[href] {
color: $secondary; color: $primary;
} }
} }

View File

@ -402,6 +402,9 @@
.user-stream { .user-stream {
.category {
margin-left: 3px;
}
.excerpt { .excerpt {
margin: 5px 0; margin: 5px 0;
font-size: 0.929em; font-size: 0.929em;

View File

@ -71,15 +71,8 @@ module UserNotificationsHelper
category_url = "#{Discourse.base_url}#{category.url}" category_url = "#{Discourse.base_url}#{category.url}"
if opts[:only_stripe] result << "<a href='#{category_url}' style='background-color: ##{category.color}; font-size: 12px; padding: 2px 1px; font-weight: bold; margin: 0; width: 2px; white-space:nowrap;'>&nbsp;</a>"
result << "<a href='#{category_url}' style='background-color: ##{category.color}; font-size: 12px; padding: 2px 1px; font-weight: bold; margin: 0; width: 2px; white-space:nowrap;'>&nbsp;</a>" result << "<a href='#{category_url}' style='font-size: 12px; font-weight: bold; margin-left: 3px; color: #222;'>#{category.name}</a>"
result << "<a href='#{category_url}' style='font-size: 12px; font-weight: bold; margin-left: 3px; color: #222;'>#{category.name}</a>"
else
if category.parent_category.present?
result << "<a href='#{category_url}' style='background-color: ##{category.parent_category.color}; font-size: 12px; padding: 4px 2px; font-weight: bold; margin: 0; width: 2px; white-space:nowrap;'>&nbsp;</a>"
end
result << "<a href='#{category_url}' style='background-color: ##{category.color}; color: ##{category.text_color}; font-size: 12px; padding: 4px 6px; font-weight: bold; margin: 0; white-space:nowrap;'>#{category.name}</a>"
end
result.html_safe result.html_safe
end end

View File

@ -45,7 +45,7 @@
<li> <li>
<%= link_to t.title, "#{Discourse.base_url}#{t.relative_url}" %> <%= link_to t.title, "#{Discourse.base_url}#{t.relative_url}" %>
<span class='post-count'><%= t('user_notifications.digest.posts', count: t.posts_count) %></span> <span class='post-count'><%= t('user_notifications.digest.posts', count: t.posts_count) %></span>
<%= email_category(t.category, only_stripe: true) %> <%= email_category(t.category) %>
</li> </li>
</ul> </ul>
<%- end -%> <%- end -%>

View File

@ -0,0 +1,41 @@
module("categoryBadgeHTML");
import { categoryBadgeHTML } from "discourse/helpers/category-link";
test("categoryBadge without a category", function() {
blank(categoryBadgeHTML(), "it returns no HTML");
});
test("Regular categoryBadge", function() {
var category = Discourse.Category.create({
name: 'hello',
id: 123,
description_text: 'cool description',
color: 'ff0',
text_color: 'f00'
}),
tag = parseHTML(categoryBadgeHTML(category))[0];
equal(tag.name, 'span', 'it creates a `span` wrapper tag');
equal(tag.attributes['class'], 'badge-wrapper', 'it has the correct class');
var label = tag.children[1];
equal(label.attributes.title, 'cool description', 'it has the correct title');
equal(label.children[0].data, 'hello', 'it has the category name');
});
test("undefined color", function() {
var noColor = Discourse.Category.create({ name: 'hello', id: 123 }),
tag = parseHTML(categoryBadgeHTML(noColor))[0];
blank(tag.attributes.style, "it has no color style because there are no colors");
});
test("allowUncategorized", function() {
var uncategorized = Discourse.Category.create({name: 'uncategorized', id: 345});
sandbox.stub(Discourse.Site, 'currentProp').withArgs('uncategorized_category_id').returns(345);
blank(categoryBadgeHTML(uncategorized), "it doesn't return HTML for uncategorized by default");
present(categoryBadgeHTML(uncategorized, {allowUncategorized: true}), "it returns HTML");
});

View File

@ -2,46 +2,6 @@ module("Discourse.HTML");
var html = Discourse.HTML; var html = Discourse.HTML;
test("categoryBadge without a category", function() {
blank(html.categoryBadge(), "it returns no HTML");
});
test("Regular categoryBadge", function() {
var category = Discourse.Category.create({
name: 'hello',
id: 123,
description_text: 'cool description',
color: 'ff0',
text_color: 'f00'
}),
tag = parseHTML(html.categoryBadge(category))[0];
equal(tag.name, 'a', 'it creates an `a` tag');
equal(tag.attributes['class'], 'badge-category', 'it has the correct class');
equal(tag.attributes.title, 'cool description', 'it has the correct title');
ok(tag.attributes.style.indexOf('#ff0') !== -1, "it has the color style");
ok(tag.attributes.style.indexOf('#f00') !== -1, "it has the textColor style");
equal(tag.children[0].data, 'hello', 'it has the category name');
});
test("undefined color", function() {
var noColor = Discourse.Category.create({ name: 'hello', id: 123 }),
tag = parseHTML(html.categoryBadge(noColor))[0];
blank(tag.attributes.style, "it has no color style because there are no colors");
});
test("allowUncategorized", function() {
var uncategorized = Discourse.Category.create({name: 'uncategorized', id: 345});
sandbox.stub(Discourse.Site, 'currentProp').withArgs('uncategorized_category_id').returns(345);
blank(html.categoryBadge(uncategorized), "it doesn't return HTML for uncategorized by default");
present(html.categoryBadge(uncategorized, {allowUncategorized: true}), "it returns HTML");
});
test("customHTML", function() { test("customHTML", function() {
blank(html.getCustomHTML('evil'), "there is no custom HTML for a key by default"); blank(html.getCustomHTML('evil'), "there is no custom HTML for a key by default");