Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 18 additions & 10 deletions javascripts/discourse/components/categories-groups.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,6 @@ import { service } from "@ember/service";
import { slugify } from "discourse/lib/utilities";
import { i18n } from "discourse-i18n";

function parseSettings(settings) {
return settings.split("|").map((i) => {
const [categoryGroup, categories] = i.split(":").map((str) => str.trim());
return { categoryGroup, categories };
});
}

const ExtraLink = class {
constructor(args) {
this.isExtraLink = true;
Expand Down Expand Up @@ -38,8 +31,17 @@ export default class CategoriesGroups extends Component {
}

get categoryGroupList() {
const parsedSettings = parseSettings(settings.category_groups);
const extraLinks = JSON.parse(settings.extra_links || "[]");
const parsedSettings = settings.grouped_categories;
const extraLinks = settings.links;

let currentUserGroups = [0];
const currentUser = this.currentUser;

if (currentUser) {
currentUser.groups.filter((group) => {
currentUserGroups.push(group.id);
});
}

// Initialize an array to keep track of found categories and used links
const foundCategories = [];
Expand All @@ -52,6 +54,7 @@ export default class CategoriesGroups extends Component {
const categoryGroupList = parsedSettings.reduce((groups, obj) => {
const categoryArray = obj.categories.split(",").map((str) => str.trim());
const categoryGroup = [];
const categoryGroupVisibility = obj.visibility ?? [0];

// Iterate through each category/link in the order specified in settings
categoryArray.forEach((categoryOrLinkId) => {
Expand All @@ -71,9 +74,14 @@ export default class CategoriesGroups extends Component {
}
});

if (categoryGroup.length > 0) {
const displayGroup = categoryGroupVisibility.some((group) =>
currentUserGroups.includes(group)
);

if (displayGroup && categoryGroup.length > 0) {
groups.push({ name: obj.categoryGroup, items: categoryGroup });
}

return groups;
}, []);

Expand Down
37 changes: 35 additions & 2 deletions locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,41 @@ en:
theme_metadata:
description: "custom category page with group settings"
settings:
category_groups: "Format as: Group name: category-slug, extra-link-id, category-slug-2"
extra_links: "Extra links that can be mixed into category list. Add link ID in category_groups setting to render"
grouped_categories:
description: "Group categories together"
schema:
properties:
categoryGroup:
label: "Group heading"
description: "The name of the group"
categories:
label: "Slugs"
description: "The category slugs and/or extra-link IDs, separated by commas."
visibility:
label: "Visibility"
description: "The user groups that can see this category group. Leave empty, or select 'everyone' to show to all users."
links:
description: "Extra links that can be mixed into category list. Add link ID in Grouped categories setting to render"
schema:
properties:
id:
label: "ID"
description: "The ID of the link"
url:
label: "URL"
description: "The URL of the link"
color:
label: "Color"
description: "CSS compatible hexadecimal color code for the link. ie. #F1592A"
title:
label: "Title"
description: "The title of the link"
description:
label: "Description"
description: "The description of the link"
icon:
label: "Icon"
description: "The icon of the link"
show_on_mobile: "Show the collapsible category box groups on mobile"
show_ungrouped: "Display a group of categories that aren't assigned to another group"
hide_muted_subcategories: "When enabled, a non-muted parent category will not appear under the muted section if it has a muted subcategory"
Expand Down
20 changes: 20 additions & 0 deletions migrations/settings/0001-use-objects.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export default function migrate(settings) {
if (settings.has("category_groups")) {
const groups = settings.get("category_groups");
const categoryGroups = groups.split("|").map((i) => {
const [categoryGroup, categories] = i.split(":").map((str) => str.trim());
return { categoryGroup, categories, visibility: [0] };
});

settings.set("grouped_categories", categoryGroups);
settings.delete("category_groups");
}

if (settings.has("extra_links")) {
const links = settings.get("extra_links");
settings.set("links", JSON.parse(links || "[]"));
settings.delete("extra_links");
}

return settings;
}
105 changes: 58 additions & 47 deletions settings.yml
Original file line number Diff line number Diff line change
@@ -1,52 +1,63 @@
category_groups:
type: "list"
default: "Default Categories: staff, site-feedback, lounge"
extra_links:
default: >
[]
json_schema: >-
grouped_categories:
refresh: true
type: objects
default: [
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "ID",
"description": "A unique identifier for the link"
},
"url": {
"type": "string",
"title": "URL",
"description": "The URL for the link"
},
"color": {
"type": "string",
"title": "Color",
"description": "The color associated with the link",
"format": "color"
},
"title": {
"type": "string",
"title": "Title",
"description": "The title of the link"
},
"description": {
"type": "string",
"format": "markdown",
"title": "Description",
"description": "A short description of the link"
},
"icon": {
"type": "string",
"title": "Icon",
"description": "An icon for the link. Example: heart",
"default": ""
}
},
"required": ["id", "url", "title", "color"]
}
"categoryGroup": "Default Categories",
"categories": "staff, site-feedback, lounge",
"visibility": [
0
]
}
]
schema:
name: "Category Groups"
identifier: categoryGroup
properties:
categoryGroup:
type: string
required: true
categories:
type: string
required: true
visibility:
type: groups
min: 1

links:
refresh: true
type: objects
default: [
{
"id": "example",
"url": "https://example.com",
"color": "#F1592A",
"title": "Example Link",
"description": "This is an example link",
"icon": ""
}
]
schema:
name: "Links"
identifier: id
properties:
id:
type: string
required: true
url:
type: string
required: true
url: true
color:
type: string
required: true
title:
type: string
required: true
description:
type: string
icon:
type: string

show_on_mobile:
default: true
Expand Down
12 changes: 9 additions & 3 deletions spec/system/custom_category_group_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def self.description
before do
sign_in(Fabricate(:admin))
theme_component.update_setting(
:extra_links,
:links,
[
{
"id" => ExampleGroupLink.id,
Expand All @@ -32,8 +32,14 @@ def self.description
)
theme_component.update_setting(:fancy_styling, true)
theme_component.update_setting(
:category_groups,
"Default Categories: #{ExampleGroupLink.id}, #{category.slug}",
:grouped_categories,
[
{
"categoryGroup" => "Default Categories",
"categories" => "#{ExampleGroupLink.id}, #{category.slug}",
"visibility" => [0],
},
].to_json,
)
SiteSetting.desktop_category_page_style = "categories_boxes"
theme_component.save!
Expand Down