diff --git a/app/assets/javascripts/discourse/app/components/sidebar/anonymous/categories-section.hbs b/app/assets/javascripts/discourse/app/components/sidebar/anonymous/categories-section.hbs
new file mode 100644
index 00000000000..f8541894e7c
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/components/sidebar/anonymous/categories-section.hbs
@@ -0,0 +1,22 @@
+
+
+ {{#each this.sectionLinks as |sectionLink|}}
+
+
+ {{/each}}
+
+
diff --git a/app/assets/javascripts/discourse/app/components/sidebar/anonymous/categories-section.js b/app/assets/javascripts/discourse/app/components/sidebar/anonymous/categories-section.js
new file mode 100644
index 00000000000..39aea7eabbb
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/components/sidebar/anonymous/categories-section.js
@@ -0,0 +1,36 @@
+import { cached } from "@glimmer/tracking";
+import { inject as service } from "@ember/service";
+import Component from "@glimmer/component";
+import CategorySectionLink from "discourse/lib/sidebar/user/categories-section/category-section-link";
+
+export default class SidebarAnonymousCategoriesSection extends Component {
+ @service topicTrackingState;
+ @service site;
+ @service siteSettings;
+
+ @cached
+ get sectionLinks() {
+ let categories = this.site.categoriesList;
+
+ if (this.siteSettings.default_sidebar_categories) {
+ const defaultCategoryIds = this.siteSettings.default_sidebar_categories
+ .split("|")
+ .map((categoryId) => parseInt(categoryId, 10));
+
+ categories = categories.filter((category) =>
+ defaultCategoryIds.includes(category.id)
+ );
+ } else {
+ categories = categories
+ .filter((category) => !category.parent_category_id)
+ .slice(0, 5);
+ }
+
+ return categories.map((category) => {
+ return new CategorySectionLink({
+ category,
+ topicTrackingState: this.topicTrackingState,
+ });
+ });
+ }
+}
diff --git a/app/assets/javascripts/discourse/app/components/sidebar/anonymous/sections.hbs b/app/assets/javascripts/discourse/app/components/sidebar/anonymous/sections.hbs
index 17f3217c72e..cc088f932db 100644
--- a/app/assets/javascripts/discourse/app/components/sidebar/anonymous/sections.hbs
+++ b/app/assets/javascripts/discourse/app/components/sidebar/anonymous/sections.hbs
@@ -1,3 +1,6 @@
diff --git a/app/assets/javascripts/discourse/app/components/sidebar/anonymous/sections.js b/app/assets/javascripts/discourse/app/components/sidebar/anonymous/sections.js
index 0c70e042df6..6cb84571db2 100644
--- a/app/assets/javascripts/discourse/app/components/sidebar/anonymous/sections.js
+++ b/app/assets/javascripts/discourse/app/components/sidebar/anonymous/sections.js
@@ -1,3 +1,6 @@
import Component from "@glimmer/component";
+import { inject as service } from "@ember/service";
-export default class SidebarAnonymousSections extends Component {}
+export default class SidebarAnonymousSections extends Component {
+ @service siteSettings;
+}
diff --git a/app/assets/javascripts/discourse/app/components/sidebar/anonymous/tags-section.hbs b/app/assets/javascripts/discourse/app/components/sidebar/anonymous/tags-section.hbs
new file mode 100644
index 00000000000..85dcfc0b32f
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/components/sidebar/anonymous/tags-section.hbs
@@ -0,0 +1,18 @@
+
+
+ {{#each this.sectionLinks as |sectionLink|}}
+
+
+ {{/each}}
+
+
diff --git a/app/assets/javascripts/discourse/app/components/sidebar/anonymous/tags-section.js b/app/assets/javascripts/discourse/app/components/sidebar/anonymous/tags-section.js
new file mode 100644
index 00000000000..0dc3804ba51
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/components/sidebar/anonymous/tags-section.js
@@ -0,0 +1,27 @@
+import { cached } from "@glimmer/tracking";
+import Component from "@glimmer/component";
+import { inject as service } from "@ember/service";
+import TagSectionLink from "discourse/lib/sidebar/user/tags-section/tag-section-link";
+
+export default class SidebarAnonymousTagsSection extends Component {
+ @service router;
+ @service topicTrackingState;
+ @service site;
+
+ @cached
+ get sectionLinks() {
+ let tags;
+
+ if (this.site.anonymous_default_sidebar_tags) {
+ tags = this.site.anonymous_default_sidebar_tags;
+ } else {
+ tags = this.site.top_tags.slice(0, 5);
+ }
+ return tags.map((tagName) => {
+ return new TagSectionLink({
+ tagName,
+ topicTrackingState: this.topicTrackingState,
+ });
+ });
+ }
+}
diff --git a/app/assets/javascripts/discourse/app/components/sidebar/user/tags-section.js b/app/assets/javascripts/discourse/app/components/sidebar/user/tags-section.js
index f3b11416cfd..59649c991fd 100644
--- a/app/assets/javascripts/discourse/app/components/sidebar/user/tags-section.js
+++ b/app/assets/javascripts/discourse/app/components/sidebar/user/tags-section.js
@@ -38,14 +38,14 @@ export default class SidebarUserTagsSection extends Component {
if (tag.pm_only) {
links.push(
new PMTagSectionLink({
- tag,
+ tagName: tag.name,
currentUser: this.currentUser,
})
);
} else {
links.push(
new TagSectionLink({
- tag,
+ tagName: tag.name,
topicTrackingState: this.topicTrackingState,
})
);
diff --git a/app/assets/javascripts/discourse/app/lib/sidebar/user/tags-section/pm-tag-section-link.js b/app/assets/javascripts/discourse/app/lib/sidebar/user/tags-section/pm-tag-section-link.js
index aec926b6013..fceac26abf6 100644
--- a/app/assets/javascripts/discourse/app/lib/sidebar/user/tags-section/pm-tag-section-link.js
+++ b/app/assets/javascripts/discourse/app/lib/sidebar/user/tags-section/pm-tag-section-link.js
@@ -1,15 +1,15 @@
export default class PMTagSectionLink {
- constructor({ tag, currentUser }) {
- this.tag = tag;
+ constructor({ tagName, currentUser }) {
+ this.tagName = tagName;
this.currentUser = currentUser;
}
get name() {
- return this.tag.name;
+ return this.tagName;
}
get models() {
- return [this.currentUser, this.tag.name];
+ return [this.currentUser, this.tagName];
}
get route() {
@@ -17,6 +17,6 @@ export default class PMTagSectionLink {
}
get text() {
- return this.tag.name;
+ return this.tagName;
}
}
diff --git a/app/assets/javascripts/discourse/app/lib/sidebar/user/tags-section/tag-section-link.js b/app/assets/javascripts/discourse/app/lib/sidebar/user/tags-section/tag-section-link.js
index dd24165a494..48f55a317ec 100644
--- a/app/assets/javascripts/discourse/app/lib/sidebar/user/tags-section/tag-section-link.js
+++ b/app/assets/javascripts/discourse/app/lib/sidebar/user/tags-section/tag-section-link.js
@@ -8,8 +8,8 @@ export default class TagSectionLink {
@tracked totalUnread = 0;
@tracked totalNew = 0;
- constructor({ tag, topicTrackingState }) {
- this.tagName = tag.name;
+ constructor({ tagName, topicTrackingState }) {
+ this.tagName = tagName;
this.topicTrackingState = topicTrackingState;
this.refreshCounts();
}
diff --git a/app/assets/javascripts/discourse/tests/acceptance/sidebar-anonymous-categories-section-test.js b/app/assets/javascripts/discourse/tests/acceptance/sidebar-anonymous-categories-section-test.js
new file mode 100644
index 00000000000..fa0e7717d31
--- /dev/null
+++ b/app/assets/javascripts/discourse/tests/acceptance/sidebar-anonymous-categories-section-test.js
@@ -0,0 +1,53 @@
+import { test } from "qunit";
+import { visit } from "@ember/test-helpers";
+import {
+ acceptance,
+ exists,
+ queryAll,
+} from "discourse/tests/helpers/qunit-helpers";
+
+acceptance("Sidebar - Anonymous Categories Section", function (needs) {
+ needs.settings({
+ enable_experimental_sidebar_hamburger: true,
+ enable_sidebar: true,
+ suppress_uncategorized_badge: false,
+ });
+
+ test("category section links", async function (assert) {
+ await visit("/");
+
+ const categories = queryAll(
+ ".sidebar-section-categories .sidebar-section-link-wrapper"
+ );
+ assert.strictEqual(categories.length, 6);
+ assert.strictEqual(categories[0].textContent.trim(), "support");
+ assert.strictEqual(categories[1].textContent.trim(), "bug");
+ assert.strictEqual(categories[2].textContent.trim(), "feature");
+ assert.strictEqual(categories[3].textContent.trim(), "dev");
+ assert.strictEqual(categories[4].textContent.trim(), "ux");
+
+ assert.ok(
+ exists("a.sidebar-section-link-more-categories"),
+ "more link is visible"
+ );
+ });
+
+ test("default sidebar categories", async function (assert) {
+ this.siteSettings.default_sidebar_categories = "3|13|1";
+ await visit("/");
+
+ const categories = queryAll(
+ ".sidebar-section-categories .sidebar-section-link-wrapper"
+ );
+
+ assert.strictEqual(categories.length, 4);
+ assert.strictEqual(categories[0].textContent.trim(), "bug");
+ assert.strictEqual(categories[1].textContent.trim(), "meta");
+ assert.strictEqual(categories[2].textContent.trim(), "blog");
+
+ assert.ok(
+ exists("a.sidebar-section-link-more-categories"),
+ "more link is visible"
+ );
+ });
+});
diff --git a/app/assets/javascripts/discourse/tests/acceptance/sidebar-anonymous-tags-section-test.js b/app/assets/javascripts/discourse/tests/acceptance/sidebar-anonymous-tags-section-test.js
new file mode 100644
index 00000000000..386e398a68f
--- /dev/null
+++ b/app/assets/javascripts/discourse/tests/acceptance/sidebar-anonymous-tags-section-test.js
@@ -0,0 +1,89 @@
+import { test } from "qunit";
+import { visit } from "@ember/test-helpers";
+import {
+ acceptance,
+ exists,
+ queryAll,
+} from "discourse/tests/helpers/qunit-helpers";
+
+acceptance("Sidebar - Anonymous Tags Section", function (needs) {
+ needs.settings({
+ enable_experimental_sidebar_hamburger: true,
+ enable_sidebar: true,
+ suppress_uncategorized_badge: false,
+ tagging_enabled: true,
+ });
+
+ needs.site({
+ top_tags: ["design", "development", "fun"],
+ });
+
+ test("tag section links", async function (assert) {
+ await visit("/");
+
+ const categories = queryAll(
+ ".sidebar-section-tags .sidebar-section-link-wrapper"
+ );
+ assert.strictEqual(categories.length, 4);
+ assert.strictEqual(categories[0].textContent.trim(), "design");
+ assert.strictEqual(categories[1].textContent.trim(), "development");
+ assert.strictEqual(categories[2].textContent.trim(), "fun");
+
+ assert.ok(
+ exists("a.sidebar-section-link-more-tags"),
+ "more link is visible"
+ );
+ });
+});
+
+acceptance("Sidebar - Anonymous Tags Section - default tags", function (needs) {
+ needs.settings({
+ enable_experimental_sidebar_hamburger: true,
+ enable_sidebar: true,
+ suppress_uncategorized_badge: false,
+ tagging_enabled: true,
+ });
+
+ needs.site({
+ top_tags: ["design", "development", "fun"],
+ anonymous_default_sidebar_tags: ["random", "meta"],
+ });
+
+ test("tag section links", async function (assert) {
+ await visit("/");
+
+ const categories = queryAll(
+ ".sidebar-section-tags .sidebar-section-link-wrapper"
+ );
+ assert.strictEqual(categories.length, 3);
+ assert.strictEqual(categories[0].textContent.trim(), "random");
+ assert.strictEqual(categories[1].textContent.trim(), "meta");
+
+ assert.ok(
+ exists("a.sidebar-section-link-more-tags"),
+ "more link is visible"
+ );
+ });
+});
+
+acceptance(
+ "Sidebar - Anonymous Tags Section - Tagging disabled",
+ function (needs) {
+ needs.settings({
+ enable_experimental_sidebar_hamburger: true,
+ enable_sidebar: true,
+ suppress_uncategorized_badge: false,
+ tagging_enabled: false,
+ });
+
+ needs.site({
+ top_tags: ["design", "development", "fun"],
+ });
+
+ test("tag section links", async function (assert) {
+ await visit("/");
+
+ assert.ok(!exists(".sidebar-section-tags"), "section is not visible");
+ });
+ }
+);
diff --git a/app/models/user.rb b/app/models/user.rb
index fea9e07ebc8..61feea4144f 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1670,6 +1670,15 @@ class User < ActiveRecord::Base
categories_ids
end
+ def sidebar_tags
+ return custom_sidebar_tags if custom_sidebar_tags.present?
+ if SiteSetting.default_sidebar_tags.present?
+ tag_names = SiteSetting.default_sidebar_tags.split("|") - DiscourseTagging.hidden_tag_names(guardian)
+ return Tag.where(name: tag_names)
+ end
+ Tag.none
+ end
+
protected
def badge_grant
@@ -1962,15 +1971,6 @@ class User < ActiveRecord::Base
end
end
- def sidebar_tags
- return custom_sidebar_tags if custom_sidebar_tags.present?
- if SiteSetting.default_sidebar_tags.present?
- tag_names = SiteSetting.default_sidebar_tags.split("|") - DiscourseTagging.hidden_tag_names(guardian)
- return Tag.where(name: tag_names)
- end
- []
- end
-
def self.ensure_consistency!
DB.exec <<~SQL
UPDATE users
diff --git a/app/serializers/site_serializer.rb b/app/serializers/site_serializer.rb
index aa68f845f02..fa396d1a62d 100644
--- a/app/serializers/site_serializer.rb
+++ b/app/serializers/site_serializer.rb
@@ -35,7 +35,8 @@ class SiteSerializer < ApplicationSerializer
:categories,
:markdown_additional_options,
:displayed_about_plugin_stat_groups,
- :show_welcome_topic_banner
+ :show_welcome_topic_banner,
+ :anonymous_default_sidebar_tags
)
has_many :archetypes, embed: :objects, serializer: ArchetypeSerializer
@@ -218,6 +219,14 @@ class SiteSerializer < ApplicationSerializer
Site.show_welcome_topic_banner?(scope)
end
+ def anonymous_default_sidebar_tags
+ User.new.sidebar_tags.pluck(:name)
+ end
+
+ def include_anonymous_default_sidebar_tags?
+ SiteSetting.default_sidebar_tags.present?
+ end
+
private
def ordered_flags(flags)
diff --git a/spec/serializers/site_serializer_spec.rb b/spec/serializers/site_serializer_spec.rb
index f815b5afa07..2839ac774ef 100644
--- a/spec/serializers/site_serializer_spec.rb
+++ b/spec/serializers/site_serializer_spec.rb
@@ -124,4 +124,15 @@ RSpec.describe SiteSerializer do
serialized = described_class.new(Site.new(admin_guardian), scope: admin_guardian, root: false).as_json
expect(serialized[:show_welcome_topic_banner]).to eq(true)
end
+
+ it 'includes anonymous_default_sidebar_tags' do
+ Fabricate(:tag, name: "dev")
+ Fabricate(:tag, name: "random")
+ serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
+ expect(serialized[:anonymous_default_sidebar_tags]).to eq(nil)
+
+ SiteSetting.default_sidebar_tags = "dev|random"
+ serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
+ expect(serialized[:anonymous_default_sidebar_tags]).to eq(["dev", "random"])
+ end
end