FEATURE: remove category badge style options, set bullet style as default (#24198)

This commit is contained in:
Kris 2023-11-13 10:46:15 -05:00 committed by GitHub
parent 70b72ee893
commit 797da5870b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
68 changed files with 302 additions and 887 deletions

View File

@ -5,7 +5,6 @@ import Mixin from "@ember/object/mixin";
import { inject as service } from "@ember/service";
import { htmlSafe } from "@ember/template";
import { isNone } from "@ember/utils";
import { categoryLinkHTML } from "discourse/helpers/category-link";
import { ajax } from "discourse/lib/ajax";
import { fmt, propertyNotEqual } from "discourse/lib/computed";
import { splitString } from "discourse/lib/utilities";
@ -113,14 +112,6 @@ export default Mixin.create({
@discourseComputed("setting", "buffered.value")
preview(setting, value) {
// A bit hacky, but allows us to use helpers
if (setting.setting === "category_style") {
const category = this.site.get("categories.firstObject");
if (category) {
return categoryLinkHTML(category, { categoryStyle: value });
}
}
const preview = setting.preview;
if (preview) {
const escapedValue = preview.replace(/\{\{value\}\}/g, value);

View File

@ -15,7 +15,21 @@
{{#each this.categoryBreadcrumbs as |breadcrumb|}}
{{#if breadcrumb.hasOptions}}
<li>
<li
style={{html-safe
(if
breadcrumb.category
(concat
"--category-bg-color:#"
breadcrumb.category.color
"; "
"--category-text-color:#"
breadcrumb.category.text_color
";"
)
)
}}
>
<CategoryDrop
@category={{breadcrumb.category}}
@categories={{breadcrumb.options}}

View File

@ -1,10 +1,9 @@
{{#each this.categories as |c|}}
<div
data-notification-level={{c.notificationLevelString}}
style={{unless this.noCategoryStyle (category-color-variable c.color)}}
style={{category-color-variable c.color}}
class="category category-box category-box-{{c.slug}}
{{if c.isMuted 'muted'}}
{{if this.noCategoryStyle 'no-category-boxes-style'}}"
{{if c.isMuted 'muted'}}"
>
<div class="category-box-inner">
<div class="category-box-heading">

View File

@ -1,5 +1,4 @@
import Component from "@ember/component";
import { equal } from "@ember/object/computed";
import { isEmpty } from "@ember/utils";
import discourseComputed from "discourse-common/utils/decorators";
@ -9,7 +8,6 @@ export default Component.extend({
":category-boxes-with-topics",
"anyLogos:with-logos:no-logos",
],
noCategoryStyle: equal("siteSettings.category_style", "none"),
lockIcon: "lock",
@discourseComputed("categories.[].uploaded_logo.url")

View File

@ -5,13 +5,12 @@
/>
<div
style={{unless this.noCategoryStyle (category-color-variable c.color)}}
style={{category-color-variable c.color}}
data-category-id={{c.id}}
data-notification-level={{c.notificationLevelString}}
data-url={{c.url}}
class="category category-box category-box-{{c.slug}}
{{if c.isMuted 'muted'}}
{{if this.noCategoryStyle 'no-category-boxes-style'}}"
{{if c.isMuted 'muted'}}"
>
<div class="category-box-inner">
{{#unless c.isMuted}}

View File

@ -1,5 +1,4 @@
import Component from "@ember/component";
import { equal } from "@ember/object/computed";
import { isEmpty } from "@ember/utils";
import discourseComputed from "discourse-common/utils/decorators";
@ -10,7 +9,6 @@ export default Component.extend({
"anyLogos:with-logos:no-logos",
"hasSubcategories:with-subcategories",
],
noCategoryStyle: equal("siteSettings.category_style", "none"),
lockIcon: "lock",
@discourseComputed("categories.[].uploaded_logo.url")

View File

@ -1,12 +1,10 @@
import Component from "@ember/component";
import { action } from "@ember/object";
import { equal } from "@ember/object/computed";
import discourseComputed from "discourse-common/utils/decorators";
export default Component.extend({
tagName: "",
showMuted: false,
noCategoryStyle: equal("siteSettings.category_style", "none"),
@discourseComputed("showMutedCategories", "filteredCategories.length")
mutedToggleIcon(showMutedCategories, filteredCategoriesLength) {

View File

@ -62,43 +62,36 @@
{{/if}}
<section class="field category-colors">
{{#if this.noCategoryStyle}}
<label>
{{d-icon "exclamation-triangle"}}
{{i18n "category.colors_disabled"}}
</label>
{{else}}
<label>{{i18n "category.badge_colors"}}</label>
<div class="category-color-editor">
{{html-safe this.categoryBadgePreview}}
<label>{{i18n "category.badge_colors"}}</label>
<div class="category-color-editor">
{{html-safe this.categoryBadgePreview}}
<section class="field">
<span class="color-title">{{i18n "category.background_color"}}:</span>
<div class="colorpicker-wrapper">
<ColorInput
@hexValue={{this.category.color}}
@valid={{this.category.colorValid}}
/>
<ColorPicker
@colors={{this.backgroundColors}}
@usedColors={{this.usedBackgroundColors}}
@value={{this.category.color}}
/>
</div>
</section>
<section class="field">
<span class="color-title">{{i18n "category.background_color"}}:</span>
<div class="colorpicker-wrapper">
<ColorInput
@hexValue={{this.category.color}}
@valid={{this.category.colorValid}}
/>
<ColorPicker
@colors={{this.backgroundColors}}
@usedColors={{this.usedBackgroundColors}}
@value={{this.category.color}}
/>
</div>
</section>
<section class="field">
<span class="color-title">{{i18n "category.foreground_color"}}:</span>
<div class="colorpicker-wrapper edit-text-color">
<ColorInput @hexValue={{this.category.text_color}} />
<ColorPicker
@colors={{this.foregroundColors}}
@value={{this.category.text_color}}
@id="edit-text-color"
/>
</div>
</section>
</div>
{{/if}}
<section class="field">
<span class="color-title">{{i18n "category.foreground_color"}}:</span>
<div class="colorpicker-wrapper edit-text-color">
<ColorInput @hexValue={{this.category.text_color}} />
<ColorPicker
@colors={{this.foregroundColors}}
@value={{this.category.text_color}}
@id="edit-text-color"
/>
</div>
</section>
</div>
</section>
</form>

View File

@ -53,11 +53,6 @@ export default buildCategoryPanel("general", {
.uniq();
},
@discourseComputed
noCategoryStyle() {
return this.siteSettings.category_style === "none";
},
@discourseComputed("category.id", "category.color")
usedBackgroundColors(categoryId, categoryColor) {
const categories = this.site.get("categoriesList");
@ -91,6 +86,7 @@ export default buildCategoryPanel("general", {
const c = Category.create({
name,
color,
id: category.id,
text_color: textColor,
parent_category_id: parseInt(parentCategoryId, 10),
read_restricted: category.get("read_restricted"),

View File

@ -15,13 +15,8 @@
{{if this.category.uploaded_logo.url 'has-logo' 'no-logo'}}"
>
<td
class="category
{{if this.isMuted 'muted'}}
{{if this.noCategoryStyle 'no-category-style'}}"
style={{unless
this.noCategoryStyle
(category-color-variable this.category.color)
}}
class="category {{if this.isMuted 'muted'}}"
style={{category-color-variable this.category.color}}
>
<CategoryTitleLink @category={{this.category}} />
<PluginOutlet

View File

@ -14,11 +14,6 @@ export function replaceCategoryLinkRenderer(fn) {
_renderer = fn;
}
function categoryStripe(color, classes) {
let style = color ? "style='background-color: #" + color + ";'" : "";
return "<span class='" + classes + "' " + style + "></span>";
}
let _extraIconRenderers = [];
export function addExtraIconRenderer(renderer) {
@ -85,9 +80,6 @@ export function categoryLinkHTML(category, options) {
if (options.hideParent) {
categoryOptions.hideParent = true;
}
if (options.categoryStyle) {
categoryOptions.categoryStyle = options.categoryStyle;
}
if (options.recursive) {
categoryOptions.recursive = true;
}
@ -114,10 +106,12 @@ export function defaultCategoryLinkRenderer(category, opts) {
let href = opts.link === false ? "" : url;
let tagName = opts.link === false || opts.link === "false" ? "span" : "a";
let extraClasses = opts.extraClasses ? " " + opts.extraClasses : "";
let color = get(category, "color");
let html = "";
let parentCat = null;
let categoryDir = "";
let dataAttributes = category
? `data-category-id="${get(category, "id")}"`
: "";
if (!opts.hideParent) {
parentCat = Category.findById(get(category, "parent_category_id"));
@ -125,34 +119,22 @@ export function defaultCategoryLinkRenderer(category, opts) {
let siteSettings = helperContext().siteSettings;
const categoryStyle = opts.categoryStyle || siteSettings.category_style;
if (categoryStyle !== "none") {
if (parentCat && parentCat !== category) {
html += categoryStripe(
get(parentCat, "color"),
"badge-category-parent-bg"
);
}
html += categoryStripe(color, "badge-category-bg");
}
let classNames = "badge-category clear-badge";
let classNames = `badge-category`;
if (restricted) {
classNames += " restricted";
}
let style = "";
if (categoryStyle === "box") {
style = `style="color: #${get(category, "text_color")};"`;
if (parentCat) {
classNames += ` --has-parent`;
dataAttributes += ` data-parent-category-id="${parentCat.id}"`;
}
html +=
`<span ${style} ` +
'data-drop-close="true" class="' +
classNames +
'"' +
(descriptionText ? 'title="' + descriptionText + '" ' : "") +
">";
html += `<span
${dataAttributes}
data-drop-close="true"
class="${classNames}"
${descriptionText ? 'title="' + descriptionText + '" ' : ""}
>`;
let categoryName = escapeExpression(get(category, "name"));
@ -169,10 +151,10 @@ export function defaultCategoryLinkRenderer(category, opts) {
html += iconHTML(iconName);
}
});
html += `<span class="category-name" ${categoryDir}>${categoryName}</span>`;
html += `<span class="badge-category__name" ${categoryDir}>${categoryName}</span>`;
html += "</span>";
if (opts.topicCount && categoryStyle !== "box") {
if (opts.topicCount) {
html += buildTopicCount(opts.topicCount);
}
@ -180,11 +162,14 @@ export function defaultCategoryLinkRenderer(category, opts) {
href = ` href="${href}" `;
}
extraClasses = categoryStyle ? categoryStyle + extraClasses : extraClasses;
let afterBadgeWrapper = "";
if (opts.topicCount && categoryStyle === "box") {
afterBadgeWrapper += buildTopicCount(opts.topicCount);
if (opts.plusSubcategories && opts.lastSubcategory) {
afterBadgeWrapper += `<span class="plus-subcategories">
${I18n.t("category_row.plus_subcategories", {
count: opts.plusSubcategories,
})}
</span>`;
}
return `<${tagName} class="badge-wrapper ${extraClasses}" ${href}>${html}</${tagName}>${afterBadgeWrapper}`;
return `<${tagName} class="badge-category__wrapper ${extraClasses}" ${href}>${html}</${tagName}>${afterBadgeWrapper}`;
}

View File

@ -0,0 +1,33 @@
import { get } from "@ember/object";
import Category from "discourse/models/category";
export default {
after: "category-color-css-generator",
// This generates badge CSS for each category, which is used to render category-specific elements.
initialize(owner) {
this.site = owner.lookup("service:site");
// If the site is login_required and the user is anon there will be no categories preloaded.
if (!this.site.categories) {
return;
}
const generatedCss = this.site.categories.map((category) => {
let parentCategory = Category.findById(
get(category, "parent_category_id")
);
let badgeCss = `.badge-category[data-category-id="${category.id}"] { --category-badge-color: var(--category-${category.id}-color); --category-badge-text-color: #${category.text_color}; }`;
if (parentCategory) {
badgeCss += `.badge-category[data-parent-category-id="${parentCategory.id}"] { --parent-category-badge-color: var(--category-${parentCategory.id}-color); }`;
}
return badgeCss;
});
const cssTag = document.createElement("style");
cssTag.type = "text/css";
cssTag.id = "category-badge-css-generator";
cssTag.innerHTML = generatedCss.join("\n");
document.head.appendChild(cssTag);
},
};

View File

@ -68,7 +68,7 @@ export default function (topic, params) {
isPrivateMessage,
tagsForUser,
tagName,
}) + " ";
}) + "";
}
}

View File

@ -156,7 +156,9 @@ export default createWidget("header-topic-info", {
this.attach("category-link", { category: parentCategory })
);
}
categories.push(this.attach("category-link", { category }));
categories.push(
this.attach("category-link", { category, hideParent: true })
);
this.headerElements.push(h("div.categories-wrapper", categories));
}

View File

@ -7,9 +7,15 @@ acceptance("CSS Generator", function (needs) {
needs.site({
categories: [
{ id: 1, color: "ff0000", name: "category1" },
{ id: 2, color: "333", name: "category2" },
{ id: 4, color: "2B81AF", parentCategory: { id: 1 }, name: "category3" },
{ id: 1, color: "ff0000", text_color: "ffffff", name: "category1" },
{ id: 2, color: "333", text_color: "ffffff", name: "category2" },
{
id: 4,
color: "2B81AF",
text_color: "ffffff",
parentCategory: { id: 1 },
name: "category3",
},
],
});
@ -30,6 +36,15 @@ acceptance("CSS Generator", function (needs) {
".hashtag-color--category-1 {\n background: linear-gradient(-90deg, var(--category-1-color) 50%, var(--category-1-color) 50%);\n}\n.hashtag-color--category-2 {\n background: linear-gradient(-90deg, var(--category-2-color) 50%, var(--category-2-color) 50%);\n}\n.hashtag-color--category-4 {\n background: linear-gradient(-90deg, var(--category-4-color) 50%, var(--category-1-color) 50%);\n}"
);
});
test("category badge CSS variables are generated", async function (assert) {
await visit("/");
const cssTag = document.querySelector("style#category-badge-css-generator");
assert.equal(
cssTag.innerHTML,
'.badge-category[data-category-id="1"] { --category-badge-color: var(--category-1-color); --category-badge-text-color: #ffffff; }\n.badge-category[data-category-id="2"] { --category-badge-color: var(--category-2-color); --category-badge-text-color: #ffffff; }\n.badge-category[data-category-id="4"] { --category-badge-color: var(--category-4-color); --category-badge-text-color: #ffffff; }'
);
});
});
acceptance(
@ -37,13 +52,21 @@ acceptance(
function (needs) {
needs.site({ categories: null });
needs.settings({ login_required: true });
test("category CSS variables are not generated", async function (assert) {
await visit("/");
const cssTag = document.querySelector(
"style#category-color-css-generator"
);
assert.notOk(exists(cssTag));
});
test("category badge CSS variables are not generated", async function (assert) {
await visit("/");
const cssTag = document.querySelector(
"style#category-badge-css-generator"
);
assert.notOk(exists(cssTag));
});
}
);

View File

@ -203,13 +203,13 @@ acceptance("Search - Glimmer - Anonymous", function (needs) {
);
assert.strictEqual(
secondOption.querySelector(".category-name").textContent.trim(),
secondOption.querySelector(".badge-category__name").textContent.trim(),
"bug",
"second option includes category slug"
);
assert.ok(
exists(`${contextSelector} span.badge-wrapper`),
exists(`${contextSelector} span.badge-category__wrapper`),
"category badge is a span (i.e. not a link)"
);
});
@ -706,7 +706,7 @@ acceptance("Search - Glimmer - with tagging enabled", function (needs) {
query(
".search-menu .results ul li:nth-of-type(1) .discourse-tags"
).textContent.trim(),
"dev slow",
"devslow",
"tags displayed in search results"
);
});
@ -741,8 +741,9 @@ acceptance("Search - Glimmer - with tagging enabled", function (needs) {
await click("#search-button");
assert.strictEqual(
query(".search-menu .results ul.search-menu-assistant .category-name")
.innerText,
query(
".search-menu .results ul.search-menu-assistant .badge-category__name"
).innerText,
"bug",
"Category is displayed"
);
@ -769,8 +770,9 @@ acceptance("Search - Glimmer - with tagging enabled", function (needs) {
);
assert.strictEqual(
query(".search-menu .results ul.search-menu-assistant .category-name")
.innerText,
query(
".search-menu .results ul.search-menu-assistant .badge-category__name"
).innerText,
"bug"
);
@ -996,7 +998,7 @@ acceptance("Search - Glimmer - assistant", function (needs) {
assert.strictEqual(
query(
".search-menu .results ul.search-menu-assistant .search-link .category-name"
".search-menu .results ul.search-menu-assistant .search-link .badge-category__name"
).innerText,
"support"
);
@ -1095,7 +1097,7 @@ acceptance("Search - Glimmer - assistant", function (needs) {
const firstCategory =
".search-menu .results ul.search-menu-assistant .search-link";
const firstCategoryName = query(
`${firstCategory} .category-name`
`${firstCategory} .badge-category__name`
).innerText;
await click(firstCategory);

View File

@ -138,7 +138,7 @@ acceptance("Review", function (needs) {
await visit("/review");
assert.ok(exists(`${topic} .reviewable-action.approve`));
assert.ok(!exists(`${topic} .category-name`));
assert.ok(!exists(`${topic} .badge-category__name`));
assert.strictEqual(
query(`${topic} .discourse-tag:nth-of-type(1)`).innerText,
@ -220,7 +220,7 @@ acceptance("Review", function (needs) {
"new raw contents"
);
assert.strictEqual(
query(`${topic} .category-name`).innerText.trim(),
query(`${topic} .badge-category__name`).innerText.trim(),
"support"
);
});

View File

@ -154,7 +154,7 @@ acceptance("Search - Anonymous", function (needs) {
);
assert.ok(
exists(`${contextSelector} span.badge-wrapper`),
exists(`${contextSelector} span.badge-category__wrapper`),
"category badge is a span (i.e. not a link)"
);
@ -584,7 +584,7 @@ acceptance("Search - with tagging enabled", function (needs) {
query(
".search-menu .results ul li:nth-of-type(1) .discourse-tags"
).textContent.trim(),
"dev slow",
"devslow",
"tags displayed in search results"
);
});
@ -831,7 +831,7 @@ acceptance("Search - assistant", function (needs) {
assert.ok(exists(query(firstCategory)));
const firstResultSlug = query(
`${firstCategory} .category-name`
`${firstCategory} .badge-category__name`
).textContent.trim();
await click(firstCategory);
@ -857,8 +857,9 @@ acceptance("Search - assistant", function (needs) {
await click("#search-button");
assert.strictEqual(
query(".search-menu .results ul.search-menu-assistant .category-name")
.innerText,
query(
".search-menu .results ul.search-menu-assistant .badge-category__name"
).innerText,
"bug",
"Category is displayed"
);
@ -885,8 +886,9 @@ acceptance("Search - assistant", function (needs) {
);
assert.strictEqual(
query(".search-menu .results ul.search-menu-assistant .category-name")
.innerText,
query(
".search-menu .results ul.search-menu-assistant .badge-category__name"
).innerText,
"bug"
);

View File

@ -240,6 +240,7 @@ export function testCleanup(container, app) {
function cleanupCssGeneratorTags() {
document.querySelector("style#category-color-css-generator")?.remove();
document.querySelector("style#category-badge-css-generator")?.remove();
document.querySelector("style#hashtag-css-generator")?.remove();
}

View File

@ -1,215 +0,0 @@
import { render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit";
import { NotificationLevels } from "discourse/lib/notification-levels";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { count, exists, queryAll } from "discourse/tests/helpers/qunit-helpers";
const topCategoryIds = [2, 3, 1];
let mutedCategoryIds = [];
let unreadCategoryIds = [];
let categoriesByCount = [];
module("Integration | Component | Widget | hamburger-menu", function (hooks) {
setupRenderingTest(hooks);
test("prioritize faq", async function (assert) {
this.siteSettings.faq_url = "http://example.com/faq";
this.currentUser.set("read_faq", false);
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(exists(".faq-priority"));
assert.ok(!exists(".faq-link"));
});
test("prioritize faq - user has read", async function (assert) {
this.siteSettings.faq_url = "http://example.com/faq";
this.currentUser.set("read_faq", true);
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(!exists(".faq-priority"));
assert.ok(exists(".faq-link"));
});
test("staff menu - not staff", async function (assert) {
this.currentUser.setProperties({ admin: false, moderator: false });
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(!exists(".admin-link"));
});
test("staff menu - moderator", async function (assert) {
this.currentUser.set("moderator", true);
this.currentUser.set("can_review", true);
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(exists(".admin-link"));
assert.ok(exists(".review"));
assert.ok(!exists(".settings-link"));
});
test("staff menu - admin", async function (assert) {
this.currentUser.setProperties({ admin: true });
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(exists(".settings-link"));
});
test("logged in links", async function (assert) {
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(exists(".new-topics-link"));
assert.ok(exists(".unread-topics-link"));
});
test("general links", async function (assert) {
this.owner.unregister("service:current-user");
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(!exists("li[class='']"));
assert.ok(exists(".latest-topics-link"));
assert.ok(!exists(".new-topics-link"));
assert.ok(!exists(".unread-topics-link"));
assert.ok(exists(".top-topics-link"));
assert.ok(exists(".badge-link"));
assert.ok(exists(".category-link"));
assert.ok(exists(".about-link"));
assert.ok(exists(".keyboard-shortcuts-link"));
});
let maxCategoriesToDisplay;
test("top categories - anonymous", async function (assert) {
this.owner.unregister("service:current-user");
this.siteSettings.header_dropdown_category_count = 8;
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.strictEqual(count(".category-link"), 8);
assert.deepEqual(
[...queryAll(".category-link .category-name")].map((el) => el.innerText),
this.site
.get("categoriesByCount")
.reject((c) => c.id === this.site.uncategorized_category_id)
.slice(0, 8)
.map((c) => c.name)
);
});
test("top categories - allow_uncategorized_topics", async function (assert) {
this.owner.unregister("service:current-user");
this.siteSettings.allow_uncategorized_topics = true;
this.siteSettings.header_dropdown_category_count = 8;
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.strictEqual(count(".category-link"), 8);
assert.deepEqual(
[...queryAll(".category-link .category-name")].map((el) => el.innerText),
this.site
.get("categoriesByCount")
.slice(0, 8)
.map((c) => c.name)
);
});
test("top categories", async function (assert) {
this.siteSettings.header_dropdown_category_count = 8;
maxCategoriesToDisplay = this.siteSettings.header_dropdown_category_count;
categoriesByCount = this.site
.get("categoriesByCount")
.reject((c) => c.id === this.site.uncategorized_category_id)
.slice();
categoriesByCount.every((c) => {
if (!topCategoryIds.includes(c.id)) {
if (mutedCategoryIds.length === 0) {
mutedCategoryIds.push(c.id);
c.set("notification_level", NotificationLevels.MUTED);
} else if (unreadCategoryIds.length === 0) {
unreadCategoryIds.push(c.id);
for (let i = 0; i < 5; i++) {
c.topicTrackingState.modifyState(123 + i, {
category_id: c.id,
last_read_post_number: 1,
highest_post_number: 2,
notification_level: NotificationLevels.TRACKING,
});
}
} else {
unreadCategoryIds.splice(0, 0, c.id);
for (let i = 0; i < 10; i++) {
c.topicTrackingState.modifyState(321 + i, {
category_id: c.id,
last_read_post_number: null,
created_in_new_period: true,
});
}
return false;
}
}
return true;
});
this.currentUser.set("top_category_ids", topCategoryIds);
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.strictEqual(
count(".category-link"),
maxCategoriesToDisplay,
"categories displayed limited by header_dropdown_category_count"
);
categoriesByCount = categoriesByCount.filter(
(c) => !mutedCategoryIds.includes(c.id)
);
let ids = [
...unreadCategoryIds,
...topCategoryIds,
...categoriesByCount.map((c) => c.id),
]
.uniq()
.slice(0, maxCategoriesToDisplay);
assert.deepEqual(
[...queryAll(".category-link .category-name")].map((el) => el.innerText),
ids.map(
(id) => categoriesByCount.find((category) => category.id === id).name
),
"top categories are in the correct order"
);
});
test("badges link - disabled", async function (assert) {
this.siteSettings.enable_badges = false;
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(!exists(".badge-link"));
});
test("badges link", async function (assert) {
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(exists(".badge-link"));
});
test("user directory link", async function (assert) {
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(exists(".user-directory-link"));
});
test("user directory link - disabled", async function (assert) {
this.siteSettings.enable_user_directory = false;
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(!exists(".user-directory-link"));
});
});

View File

@ -14,7 +14,7 @@ module("Integration | Helper | category-badge", function (hooks) {
await render(hbs`{{category-badge this.category}}`);
assert.strictEqual(
query(".category-name").innerText.trim(),
query(".badge-category__name").innerText.trim(),
this.category.name
);
});
@ -26,7 +26,7 @@ module("Integration | Helper | category-badge", function (hooks) {
assert.ok(
exists(
`a.badge-wrapper[href="/c/${this.category.slug}/${this.category.id}"]`
`a.badge-category__wrapper[href="/c/${this.category.slug}/${this.category.id}"]`
)
);
});

View File

@ -26,11 +26,11 @@ module("Unit | Utility | category-badge", function (hooks) {
assert.strictEqual(tag.tagName, "A", "it creates a `a` wrapper tag");
assert.strictEqual(
tag.className.trim(),
"badge-wrapper bullet",
"badge-category__wrapper",
"it has the correct class"
);
const label = tag.children[1];
const label = tag.children[0];
assert.strictEqual(
label.title,
"cool description",
@ -108,11 +108,12 @@ module("Unit | Utility | category-badge", function (hooks) {
});
let tag = $.parseHTML(categoryBadgeHTML(rtlCategory))[0];
let dirSpan = tag.children[1].children[0];
let dirSpan = tag.children[0].children[0];
assert.strictEqual(dirSpan.dir, "rtl");
tag = $.parseHTML(categoryBadgeHTML(ltrCategory))[0];
dirSpan = tag.children[1].children[0];
dirSpan = tag.children[0].children[0];
assert.strictEqual(dirSpan.dir, "ltr");
});

View File

@ -15,11 +15,9 @@ export const ALL_CATEGORIES_ID = "all-categories";
export default ComboBoxComponent.extend({
pluginApiIdentifiers: ["category-drop"],
classNameBindings: ["categoryStyle"],
classNames: ["category-drop"],
value: readOnly("category.id"),
content: readOnly("categoriesWithShortcuts.[]"),
categoryStyle: readOnly("siteSettings.category_style"),
noCategoriesLabel: I18n.t("categories.no_subcategory"),
navigateToEdit: false,
editingCategory: false,

View File

@ -1,13 +1,8 @@
import { readOnly } from "@ember/object/computed";
import { schedule } from "@ember/runloop";
import { htmlSafe } from "@ember/template";
import discourseComputed from "discourse-common/utils/decorators";
import ComboBoxSelectBoxHeaderComponent from "select-kit/components/combo-box/combo-box-header";
export default ComboBoxSelectBoxHeaderComponent.extend({
classNames: ["category-drop-header"],
classNameBindings: ["categoryStyleClass"],
categoryStyleClass: readOnly("site.category_style"),
@discourseComputed("selectedContent.color")
categoryBackgroundColor(categoryColor) {
@ -18,45 +13,4 @@ export default ComboBoxSelectBoxHeaderComponent.extend({
categoryTextColor(categoryTextColor) {
return categoryTextColor || "#333";
},
@discourseComputed(
"selectedContent",
"categoryBackgroundColor",
"categoryTextColor"
)
categoryStyle(category, categoryBackgroundColor, categoryTextColor) {
const categoryStyle = this.siteSettings.category_style;
if (categoryStyle === "bullet") {
return;
}
if (category) {
if (categoryBackgroundColor || categoryTextColor) {
let style = "";
if (categoryBackgroundColor) {
if (categoryStyle === "box") {
style += `border-color: #${categoryBackgroundColor}; background-color: #${categoryBackgroundColor};`;
if (categoryTextColor) {
style += `color: #${categoryTextColor};`;
}
}
}
return htmlSafe(style);
}
}
},
didInsertElement() {
this._super(...arguments);
schedule("afterRender", () => {
if (this.categoryStyle) {
this.element.setAttribute("style", this.categoryStyle);
this.element
.querySelector(".caret-icon")
.setAttribute("style", this.categoryStyle);
}
});
},
});

View File

@ -15,10 +15,9 @@ const MORE_TAGS_COLLECTION = "MORE_TAGS_COLLECTION";
export default ComboBoxComponent.extend(TagsMixin, {
pluginApiIdentifiers: ["tag-drop"],
classNameBindings: ["categoryStyle", "tagClass"],
classNameBindings: ["tagClass"],
classNames: ["tag-drop"],
value: readOnly("tagId"),
categoryStyle: setting("category_style"),
maxTagSearchResults: setting("max_tag_search_results"),
sortTagsAlphabetically: setting("tags_sort_alphabetically"),
maxTagsInFilterList: setting("max_tags_in_filter_list"),

View File

@ -3,11 +3,6 @@
.list-controls {
background: var(--d-content-background);
a.badge-category {
padding: 3px 12px;
font-size: var(--font-up-1);
}
.combo-box .combo-box-header {
background: var(--secondary);
color: var(--primary);
@ -129,10 +124,11 @@
a.title:not(.badge-notification) {
color: var(--primary-medium);
}
span.badge-category {
.badge-category {
color: var(--primary-medium);
}
a.discourse-tag {
.discourse-tag,
.discourse-tag:visited {
color: var(--primary-medium);
}
}
@ -258,10 +254,10 @@
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.5em;
.discourse-tags {
flex-wrap: wrap;
}
a.badge-wrapper.box,
a.discourse-tag.box {
padding-top: 0;
padding-bottom: 0;

View File

@ -227,7 +227,7 @@
align-items: center;
@include ellipsis;
margin-bottom: 0.6em;
.badge-wrapper {
.badge-category__wrapper {
overflow: hidden;
}
.subcategory-image-placeholder {

View File

@ -278,11 +278,12 @@ html.composer-open {
max-width: 100%;
overflow: hidden;
display: flex;
.badge-wrapper {
gap: 0 0.5em;
.badge-category__wrapper {
overflow: hidden;
}
// This prevents the first category from being too-truncated at the expense of a long subcategory
.badge-wrapper:first-of-type:not(:last-of-type) {
.badge-category__wrapper:first-of-type:not(:last-of-type) {
flex: 1 0 auto;
max-width: 50%;
}

View File

@ -9,7 +9,7 @@
max-width: 700px;
}
.about.category-moderators {
.badge-wrapper.bullet .badge-category {
.badge-category__wrapper .badge-category {
color: var(--primary);
}
}

View File

@ -290,6 +290,7 @@
"categories extra";
grid-template-columns: auto minmax(2em, 1fr); // min must be as wide as ellipsis
align-items: baseline;
gap: 0 0.5em;
.header-title {
grid-area: title;
}
@ -322,22 +323,14 @@
.categories-wrapper {
display: inline-flex;
flex: 0 1 auto;
gap: 0 0.5em;
@include ellipsis;
.badge-wrapper {
@include ellipsis;
}
}
.badge-wrapper {
margin-right: 0.7em;
.badge-category__wrapper {
min-width: 2.75em; // min needed for ellipsis
}
.badge-wrapper {
&.bullet,
&.bar,
&.none {
span.badge-category {
color: var(--header_primary-high);
}
@include ellipsis;
.badge-category {
color: var(--header_primary-high);
}
}
.topic-header-extra {

View File

@ -48,9 +48,6 @@
flex-wrap: wrap;
align-items: center;
gap: 0.5em;
.badge-wrapper {
margin: 0;
}
}
#display-modes {
@ -170,9 +167,6 @@
#revisions {
word-wrap: break-word;
.badge-wrapper {
margin: 0;
}
table {
margin-top: 10px;
tr {

View File

@ -274,10 +274,6 @@
.panel-body {
overflow-y: auto;
}
span.badge-category {
max-width: 100px;
}
}
.menu-links.columned {
@ -370,22 +366,6 @@
font-size: var(--font-down-1);
line-height: var(--line-height-large);
}
.badge-wrapper {
&.bar,
&.bullet {
color: var(--primary);
padding: 0 0 0 0.15em;
}
&.box {
color: var(--secondary);
+ a.badge.badge-notification {
padding-top: 2px;
}
span {
z-index: z("base") * -1;
}
}
}
}
// note these topic counts only appear for anons in the category hamburger drop down

View File

@ -611,6 +611,9 @@
max-width: 90%;
}
.topic-categories {
display: flex;
font-weight: normal;
gap: 0.5em;
width: 100%;
}
}

View File

@ -49,7 +49,7 @@
display: none;
}
}
a:not(.badge-wrapper) {
a:not(.badge-category__wrapper) {
flex-basis: 100%;
}
}

View File

@ -25,7 +25,7 @@
}
}
}
.badge-wrapper span.badge-category {
.badge-category__wrapper .badge-category {
max-width: 20em;
@include breakpoint(mobile-extra-large) {
max-width: 30vw;

View File

@ -112,13 +112,7 @@ $search-pad-horizontal: 0.5em;
display: flex;
flex-wrap: wrap;
align-items: baseline;
.badge-wrapper {
margin-right: 0.5em;
}
.discourse-tags .discourse-tag {
margin-right: 0.35em;
}
gap: 0 0.5em;
}
}
@ -255,9 +249,8 @@ $search-pad-horizontal: 0.5em;
.search-item-prefix {
margin-right: 0.33em;
}
.badge-wrapper {
.badge-category__wrapper {
font-size: var(--font-0);
margin-right: 0.5em;
}
.search-link {
display: flex;

View File

@ -301,7 +301,8 @@
display: flex;
flex-wrap: wrap;
margin-top: 0.25em;
.badge-wrapper {
gap: 0 0.5em;
.badge-category__wrapper {
max-width: 100%;
}
}
@ -313,7 +314,6 @@
.discourse-tag.simple {
font-size: var(--font-down-1);
margin-right: 0.25em;
}
}
@ -363,7 +363,6 @@
.discourse-tag.simple {
font-size: var(--font-down-1);
margin-right: 0.25em;
}
}

View File

@ -69,11 +69,11 @@
height: 15px;
}
.badge-wrapper {
.badge-category__wrapper {
font-size: 100%;
width: 100%;
.category-name {
.badge-category__name {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;

View File

@ -38,6 +38,7 @@
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.5em;
.topic-header-extra {
display: inline-flex;

View File

@ -65,9 +65,6 @@
&:not(:last-of-type) {
border-bottom: 1px solid var(--primary-low);
}
.badge-wrapper {
margin-right: 0;
}
.desc {
display: inline-block;
vertical-align: middle;
@ -114,7 +111,7 @@
max-width: 90%;
margin: 0;
}
.badge-wrapper {
.badge-category__wrapper {
white-space: nowrap;
overflow: hidden;
max-width: 19em;

View File

@ -470,10 +470,6 @@ aside.quote {
margin-top: 1em;
margin-bottom: 1em;
.badge-wrapper {
margin-left: 5px;
}
.title {
@include post-aside;
@ -1279,11 +1275,6 @@ span.mention {
.topics {
padding-bottom: 15px;
}
.suggested-topics-message {
.badge-wrapper {
margin-right: 0;
}
}
}
.large-image-placeholder {

View File

@ -265,10 +265,6 @@ $topic-progress-height: 42px;
}
}
a.badge-category {
margin-top: 5px;
}
#topic-title {
.title-wrapper {
display: flex;
@ -282,9 +278,7 @@ a.badge-category {
margin-bottom: 0;
width: 100%;
}
a.badge-category {
margin-top: 5px;
}
a.edit-topic .d-icon {
font-size: 0.8em;
}

View File

@ -15,7 +15,10 @@
// Category badges
// --------------------------------------------------
.badge-wrapper {
.badge-category__wrapper {
color: var(--primary-high);
overflow: hidden;
text-overflow: ellipsis;
font-size: var(--font-down-1);
white-space: nowrap;
position: relative;
@ -25,138 +28,42 @@
.badge-category {
display: inline-flex;
align-items: baseline;
.category-name {
text-overflow: ellipsis;
overflow: hidden;
}
.d-icon {
margin-right: 3px;
width: 0.74em;
height: 0.74em;
color: inherit;
}
}
// ----- Bullet
&.bullet {
margin-right: 12px;
span.badge-category {
color: var(--primary-high);
overflow: hidden;
.extra-info-wrapper & {
color: var(--header-primary);
}
}
.badge-category-parent-bg,
.badge-category-bg {
flex: 0 0 auto;
width: 9px;
height: 9px;
margin-right: 5px;
display: inline-block;
}
.badge-category-parent-bg {
// Subcategories
width: 5px;
margin-right: 0;
+ .badge-category-bg {
width: 5px;
}
}
.d-icon {
color: var(--primary-medium);
}
}
// ----- Box
&.box {
margin-right: 5px;
padding: 2px 4px 2px 4px;
display: inline-flex;
span {
overflow: hidden;
text-overflow: ellipsis;
&.badge-category-bg,
&.badge-category-parent-bg {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
&.badge-category-parent-bg {
// Subcategories
width: calc(100% - 5px);
& + .badge-category-bg {
left: 5px;
width: calc(100% - 5px);
& + .badge-category {
margin-left: 5px;
}
}
}
&.badge-category {
position: relative;
}
}
+ .topic-header-extra {
padding: 2px 4px 2px 4px;
}
}
// ----- Bar
&.bar {
margin-right: 5px;
span.badge-category {
color: var(--primary-high);
padding-left: 4px;
overflow: hidden;
text-overflow: ellipsis;
.extra-info-wrapper & {
color: var(--header-primary);
}
}
.badge-category-parent-bg,
.badge-category-bg {
display: inline-block;
padding-left: 1px;
padding-right: 1px;
&:before {
content: "\a0";
}
}
}
// ----- No category style
&.none {
gap: 0.33em;
color: var(--primary-high);
margin-right: 5px;
.badge-category {
&:before {
content: "";
background: var(--category-badge-color);
flex: 0 0 auto;
width: 0.67rem; // fixed dimensions because otherwise they may not be square
height: 0.67rem;
}
&__name {
color: currentColor;
text-overflow: ellipsis;
overflow: hidden;
}
}
}
// Category badge dropdown
// --------------------------------------------------
.list-controls {
.category-breadcrumb {
a.badge-category {
display: inline-block;
padding: 6px 8px;
line-height: var(--line-height-medium);
&.--has-parent {
&:before {
background: linear-gradient(
90deg,
var(--parent-category-badge-color) 50%,
var(--category-badge-color) 50%
);
}
}
.extra-info-wrapper & {
color: var(--header_primary-high);
}
}
.d-icon {
width: 0.74em;
height: 0.74em;
color: var(--primary-medium);
}
}

View File

@ -56,31 +56,12 @@
}
// Target the .badge-category text, the bullet icon needs to maintain `display: block`
.suggested-topics-message .badge-wrapper.bullet span.badge-category,
.suggested-topics-message .badge-wrapper.box span,
.suggested-topics-message .badge-wrapper.bar span {
.suggested-topics-message .badge-category__wrapper .badge-category {
display: inline;
}
.suggested-topics-message .badge-wrapper.bullet span.badge-category {
// Override vertical-align: text-top from `badges.css.scss`
vertical-align: baseline;
line-height: var(--line-height-medium);
}
.suggested-topics-message .badge-wrapper.bullet {
margin-right: 0;
}
.suggested-topics-message .badge-wrapper.bullet,
.suggested-topics-message .badge-wrapper.bullet span.badge-category-parent-bg,
.suggested-topics-message .badge-wrapper.bullet span.badge-category-bg {
// Top of bullet aligns with top of line - adjust line height to vertically align bullet.
line-height: 0.8;
}
.suggested-topics-message .badge-wrapper.bullet span.badge-category,
.suggested-topics-message .badge-wrapper.bar span.badge-category {
max-width: 150px;
}
}

View File

@ -32,7 +32,6 @@
#footer,
.alert-info,
.badge-category,
.badge-category-bg,
.badge-notification.clicks,
.crawler-nav,
.powered-by-link,

View File

@ -3,37 +3,16 @@
&.category-drop {
min-width: auto;
.badge-wrapper {
.badge-category__wrapper {
font-size: var(--font-0);
font-weight: normal;
max-width: 260px;
&.box {
margin: 0;
span.badge-category {
margin: 0;
.d-icon-lock {
margin-right: 5px;
}
}
}
}
&.box.has-selection .category-drop-header {
.badge-wrapper.box {
padding: 0;
}
}
.category-drop-header {
&.is-none .selected-name {
color: inherit;
}
.badge-wrapper {
margin-right: 0;
}
}
.select-kit-row {
@ -62,14 +41,6 @@
color: var(--primary-medium);
font-size: var(--font-down-1);
}
.badge-wrapper {
margin: 0;
&:nth-child(2) {
margin-left: 10px;
}
}
}
}
}

View File

@ -8,16 +8,11 @@
align-items: center;
max-width: 100%;
flex: 1 1 auto;
gap: 0 0.5em;
}
.category-desc p {
margin: 0;
}
.category-status {
.badge-wrapper.box {
margin-bottom: 1px;
margin-top: 1px;
}
}
.category-desc {
margin: 0;
font-size: var(--font-down-1);

View File

@ -1,21 +1,28 @@
.select-kit,
.select-kit-box {
&.category-selector {
.select-kit-selected-name {
.badge-wrapper {
&.box {
margin: 2px;
padding: 0;
}
}
}
.category-row {
max-width: 100%;
.category-status {
gap: 0 0.5em;
}
.topic-count {
margin-left: 0.25em;
}
}
.selected-choice-category {
.badge-category .d-icon {
margin: 0;
}
&:hover,
&:focus {
.badge-category {
color: var(--secondary);
}
}
}
}
}

View File

@ -128,10 +128,6 @@
border-bottom-width: 5px;
border-bottom-style: solid;
}
.badge-wrapper {
font-size: inherit;
}
}
.btn-clear {

View File

@ -59,9 +59,6 @@
align-items: baseline;
margin-right: 0.3em;
}
.badge-wrapper {
margin-right: 0.5em;
}
.badge-notification.unread-posts {
display: block;
padding: 0;

View File

@ -40,17 +40,15 @@
flex: 0 1 auto;
max-width: 65%;
font-size: var(--font-0);
.badge-wrapper {
max-width: 100%;
.badge-category-bg {
flex-shrink: 0;
}
}
.top-row {
margin-bottom: 0.1em;
font-size: var(--font-up-1);
}
.bottom-row {
display: flex;
flex-wrap: wrap;
gap: 0 0.5em;
}
}
.topic-stats {
flex: 1 0 0px;

View File

@ -7,8 +7,8 @@
.more-content-topics {
padding: 15px 0 15px 0;
a.badge-category,
a.badge-category-parent {
.badge-category,
.badge-category-parent {
font-size: var(--font-down-1);
vertical-align: top;
}

View File

@ -190,11 +190,17 @@
.topic-item-stats__category-tags {
margin-right: 0.5em;
max-width: 90%;
line-height: var(--line-height-medium);
.discourse-tags {
display: inline;
}
.badge-category__wrapper {
vertical-align: bottom;
margin-right: 0.5em;
}
.badge-wrapper,
.discourse-tag {
// disabling clicks because these targets are too small on mobile
@ -209,23 +215,6 @@
max-width: 100%;
vertical-align: bottom;
}
.badge-wrapper {
&.bullet {
+ .discourse-tags {
.discourse-tag {
vertical-align: bottom;
}
}
}
&.box {
+ .discourse-tags {
.discourse-tag {
vertical-align: text-bottom;
}
}
}
}
}
.age {
@ -379,10 +368,6 @@ tr.category-topic-link {
}
}
th .badge-category {
margin: 0;
}
.category-topic-link {
.num {
white-space: nowrap;

View File

@ -120,6 +120,10 @@ sub sub {
width: 100%;
margin-top: 0;
}
.topic-category {
margin-top: 0.25em;
}
}
// make mobile timeline top and bottom dates easier to select

View File

@ -219,8 +219,7 @@ class AdminDashboardData
:unreachable_themes,
:watched_words_check,
:google_analytics_version_check,
:translation_overrides_check,
:deprecated_category_style_check
:translation_overrides_check
register_default_scheduled_problem_checks
@ -460,10 +459,6 @@ class AdminDashboardData
themes_html_format(themes, "dashboard.unreachable_themes")
end
def deprecated_category_style_check
I18n.t("dashboard.category_style_deprecated") if SiteSetting.category_style != "bullet"
end
private
def themes_html_format(themes, i18n_key)

View File

@ -2008,7 +2008,6 @@ en:
desktop_category_page_style: "Visual style for the /categories page."
category_colors: "A list of hexadecimal color values allowed for categories."
category_style: "Visual style for category badges."
default_dark_mode_color_scheme_id: "The color scheme used when in dark mode."
dark_mode_none: "None"
@ -3033,7 +3032,7 @@ en:
reviewable_queued_post_revise_and_reject_new_topic:
title: "Feedback on your topic"
subject_template: "Feedback on new topic titled \"%{topic_title}\""
subject_template: 'Feedback on new topic titled "%{topic_title}"'
text_body_template: |
Hi %{username},

View File

@ -260,15 +260,6 @@ basic:
type: list
list_type: compact
default: "BF1E2E|F1592A|F7941D|9EB83B|3AB54A|12A89D|25AAE2|0E76BD|652D90|92278F|ED207B|8C6238|231F20|808281|B3B5B4|E45735"
category_style:
client: true
default: "bullet"
type: enum
choices:
- bar
- box
- bullet
- none
max_category_nesting:
client: true
default: 2

View File

@ -1,31 +1,6 @@
# frozen_string_literal: true
module CategoryBadge
def self.category_stripe(color, classes)
style = color ? "style='background-color: ##{color};'" : ""
"<span class='#{classes}' #{style}></span>"
end
def self.inline_category_stripe(color, styles = "", insert_blank = false)
"<span style='background-color: ##{color};#{styles}'>#{insert_blank ? "&nbsp;" : ""}</span>"
end
def self.inline_badge_wrapper_style(category)
style =
case (SiteSetting.category_style || :box).to_sym
when :bar
"line-height: 1.25; margin-right: 5px;"
when :box
"background-color:##{category.color}; line-height: 1.5; margin-top: 5px; margin-right: 5px;"
when :bullet
"line-height: 1; margin-right: 10px;"
when :none
""
end
" style='font-size: 0.857em; white-space: nowrap; display: inline-block; position: relative; #{style}'"
end
def self.html_for(category, opts = nil)
opts = opts || {}
@ -35,90 +10,32 @@ module CategoryBadge
# By default hide uncategorized
return "" if category.uncategorized? && !opts[:show_uncategorized]
extra_classes = "#{opts[:extra_classes]} #{SiteSetting.category_style}"
extra_classes = "#{opts[:extra_classes]}"
result = +""
# parent span
unless category.parent_category_id.nil? || opts[:hide_parent]
parent_category = Category.find_by(id: category.parent_category_id)
result << if opts[:inline_style]
case (SiteSetting.category_style || :box).to_sym
when :bar
inline_category_stripe(
parent_category.color,
"display: inline-block; padding: 1px;",
true,
)
when :box
inline_category_stripe(
parent_category.color,
"display: inline-block; padding: 0 1px;",
true,
)
when :bullet
inline_category_stripe(
parent_category.color,
"display: inline-block; width: 5px; height: 10px; line-height: 1;",
)
when :none
""
end
else
category_stripe(parent_category.color, "badge-category-parent-bg")
end
end
# sub parent or main category span
result << if opts[:inline_style]
case (SiteSetting.category_style || :box).to_sym
when :bar
inline_category_stripe(category.color, "display: inline-block; padding: 1px;", true)
when :box
""
when :bullet
inline_category_stripe(
category.color,
"display: inline-block; width: #{category.parent_category_id.nil? ? 10 : 5}px; height: 10px;",
)
when :none
""
end
else
category_stripe(category.color, "badge-category-bg")
end
# parent class
parent_category =
Category.find_by(id: category.parent_category_id) unless category.parent_category_id.nil?
has_parent_class = parent_category ? "--has-parent" : ""
# category name
class_names = "badge-category clear-badge"
class_names = "badge-category #{has_parent_class}"
description = category.description_text ? "title='#{category.description_text}'" : ""
category_url =
opts[:absolute_url] ? "#{Discourse.base_url_no_prefix}#{category.url}" : category.url
extra_span_classes =
if opts[:inline_style]
case (SiteSetting.category_style || :box).to_sym
when :bar
"color: #222222; padding: 3px; vertical-align: text-top; margin-top: -3px; display: inline-block;"
when :box
"color: ##{category.text_color}; padding: 0 5px;"
when :bullet
"color: #222222; vertical-align: text-top; line-height: 1; margin-left: 4px; padding-left: 2px; display: inline;"
when :none
""
end + "max-width: 150px; overflow: hidden; text-overflow: ellipsis;"
elsif (SiteSetting.category_style).to_sym == :box
"color: ##{category.text_color}"
else
""
end
result << "<span style='#{extra_span_classes}' data-drop-close='true' class='#{class_names}'
#{description}>"
result << ERB::Util.html_escape(category.name) << "</span>"
# category badge structure
result << "<span data-category-id='#{category.id}'"
result << " data-parent-category-id='#{parent_category.id}'" if parent_category
result << " data-drop-close='true' class='#{class_names}' #{description}>"
result << "<span class='badge-category__name'>"
result << ERB::Util.html_escape(category.name)
result << "</span></span>"
# wrapping link
result =
"<a class='badge-wrapper #{extra_classes}' href='#{category_url}'" +
(opts[:inline_style] ? inline_badge_wrapper_style(category) : "") + ">#{result}</a>"
"<a class='badge-category__wrapper #{extra_classes}' href='#{category_url}'>#{result}</a>"
result.html_safe
end

View File

@ -4,11 +4,9 @@
<img src="{{logo_url}}" class="thumbnail" />
{{/logo_url}}
<h3>
<a class="badge-wrapper bullet" href="{{url}}">
{{#color}}
<span class="badge-category-bg" style="background-color: #{{color}}"></span>
{{/color}}
<span class="clear-badge"><span>{{name}}</span></span>
<a class="badge-category__wrapper" href="{{url}}">
<span class="badge-category__name">{{{name}}}</span>
</span>
</a>
</h3>
{{#description}}
@ -22,9 +20,9 @@
<div class="subcategories">
{{#subcategories}}
<span class="subcategory">
<a class="badge-wrapper bullet" href="{{url}}">
<span class="badge-category-bg" style="background-color: #{{color}}"></span>
<span class="badge-category clear-badge"><span class="category-name">{{name}}</span></span>
<a class="badge-category__wrapper" href="{{url}}">
<span class="badge-category-bg" style="background-color: #{{{color}}}"></span>
<span class="badge-category clear-badge"><span class="category-name">{{{name}}}</span></span>
</a>
</span>
{{/subcategories}}

View File

@ -145,10 +145,6 @@
display: none;
margin-left: auto;
}
.badge-wrapper {
align-items: center;
margin-right: 0;
}
.emoji {
margin-left: 0.3em;

View File

@ -6,11 +6,6 @@
@include ellipsis;
}
// category badge margin reset
.badge-wrapper.bullet {
margin-right: 0;
}
.chat-retention-reminder-text {
color: var(--primary-medium);
}

View File

@ -196,9 +196,6 @@ a.chat-drawer-header__title {
}
}
.badge-wrapper.bullet {
margin-right: 0px;
}
.dm-usernames {
max-width: 100%;
overflow: hidden;

View File

@ -77,7 +77,7 @@ RSpec.describe "Channel - Info - Settings page", type: :system do
it "shows channel info" do
chat_page.visit_channel_settings(channel_1)
expect(page.find(".category-name")).to have_content(channel_1.chatable.name)
expect(page.find(".badge-category__name")).to have_content(channel_1.chatable.name)
expect(page.find(".chat-channel-settings__name")).to have_content(channel_1.title)
expect(page.find(".chat-channel-settings__slug")).to have_content(channel_1.slug)
end

View File

@ -233,9 +233,8 @@ And that too in just over an year, way to go! [boom]">
<div id="breadcrumbs" itemscope itemtype="http://schema.org/BreadcrumbList">
<div itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
<a href="https://meta.discourse.org/c/praise" class="badge-wrapper bullet" itemprop="item">
<span class="badge-category-bg"></span>
<span class="category-title" itemprop="name">praise</span>
<a href="https://meta.discourse.org/c/praise" class="badge-category__wrapper" itemprop="item">
<span class="badge-category__title" itemprop="name">praise</span>
</a>
<meta itemprop="position" content="1" />
</div>

View File

@ -225,9 +225,8 @@ And that too in just over an year, way to go! [boom]">
<div id="breadcrumbs" itemscope itemtype="http://schema.org/BreadcrumbList">
<div itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
<a href="https://meta.discourse.org/c/praise" class="badge-wrapper bullet" itemprop="item">
<span class="badge-category-bg"></span>
<span class="category-title" itemprop="name">praise</span>
<a href="https://meta.discourse.org/c/praise" class="badge-category__wrapper" itemprop="item">
<span class="badge-category__title" itemprop="name">praise</span>
</a>
<meta itemprop="position" content="1" />
</div>

View File

@ -391,26 +391,4 @@ RSpec.describe AdminDashboardData do
end
end
end
describe "#deprecated_category_style_check" do
subject(:dashboard_data) { described_class.new }
context "with a non-default category style" do
before { SiteSetting.set(:category_style, "box") }
it "outputs the correct message" do
expect(dashboard_data.deprecated_category_style_check).to eq(
I18n.t("dashboard.category_style_deprecated"),
)
end
end
context "with the default category style" do
before { SiteSetting.set(:category_style, "bullet") }
it "outputs nothing" do
expect(dashboard_data.deprecated_category_style_check).to eq(nil)
end
end
end
end

View File

@ -297,7 +297,7 @@ RSpec.describe EmailController do
navigate_to_unsubscribe
expect(response.body).to include("unwatch_category")
doc = Nokogiri::HTML5.fragment(response.body)
expect(doc.css('a.badge-wrapper[href="/c/uncategorized/1"]').size).to eq(1)
expect(doc.css('a.badge-category__wrapper[href="/c/uncategorized/1"]').size).to eq(1)
cu.destroy!

View File

@ -32,7 +32,10 @@ module PageObjects
end
def has_category_in_template_row?(category_name)
find(".form-templates__table .categories .category-name", text: category_name).present?
find(
".form-templates__table .categories .badge-category__name",
text: category_name,
).present?
end
def has_template_structure?(structure)