diff --git a/app/assets/javascripts/discourse/app/pre-initializers/dynamic-route-builders.js b/app/assets/javascripts/discourse/app/pre-initializers/dynamic-route-builders.js index b408917c6ce..ebfb4bcd698 100644 --- a/app/assets/javascripts/discourse/app/pre-initializers/dynamic-route-builders.js +++ b/app/assets/javascripts/discourse/app/pre-initializers/dynamic-route-builders.js @@ -61,6 +61,9 @@ export default { app["TagsShowCategoryNoneRoute"] = TagShowRoute.extend({ noSubcategories: true, }); + app["TagsShowCategoryAllRoute"] = TagShowRoute.extend({ + noSubcategories: false, + }); site.get("filters").forEach(function (filter) { app["TagShow" + filter.capitalize() + "Route"] = TagShowRoute.extend({ @@ -70,8 +73,11 @@ export default { "TagsShowCategory" + filter.capitalize() + "Route" ] = TagShowRoute.extend({ navMode: filter }); app[ - "TagsShowNoneCategory" + filter.capitalize() + "Route" + "TagsShowCategoryNone" + filter.capitalize() + "Route" ] = TagShowRoute.extend({ navMode: filter, noSubcategories: true }); + app[ + "TagsShowCategoryAll" + filter.capitalize() + "Route" + ] = TagShowRoute.extend({ navMode: filter, noSubcategories: false }); }); }, }; diff --git a/app/assets/javascripts/discourse/app/routes/app-route-map.js b/app/assets/javascripts/discourse/app/routes/app-route-map.js index 8e7dd439170..36d3dce2717 100644 --- a/app/assets/javascripts/discourse/app/routes/app-route-map.js +++ b/app/assets/javascripts/discourse/app/routes/app-route-map.js @@ -225,6 +225,9 @@ export default function () { this.route("showCategory", { path: "/c/*category_slug_path_with_id/:tag_id", }); + this.route("showCategoryAll", { + path: "/c/*category_slug_path_with_id/all/:tag_id", + }); this.route("showCategoryNone", { path: "/c/*category_slug_path_with_id/none/:tag_id", }); @@ -233,6 +236,9 @@ export default function () { this.route("showCategory" + filter.capitalize(), { path: "/c/*category_slug_path_with_id/:tag_id/l/" + filter, }); + this.route("showCategoryAll" + filter.capitalize(), { + path: "/c/*category_slug_path_with_id/all/:tag_id/l/" + filter, + }); this.route("showCategoryNone" + filter.capitalize(), { path: "/c/*category_slug_path_with_id/none/:tag_id/l/" + filter, }); diff --git a/app/assets/javascripts/discourse/app/routes/tag-show.js b/app/assets/javascripts/discourse/app/routes/tag-show.js index 71afbf1ea35..47d5740d2c0 100644 --- a/app/assets/javascripts/discourse/app/routes/tag-show.js +++ b/app/assets/javascripts/discourse/app/routes/tag-show.js @@ -75,8 +75,8 @@ export default DiscourseRoute.extend(FilterModeMixin, { category.setupGroupsAndPermissions(); filter = `tags/c/${Category.slugFor(category)}/${category.id}`; - if (this.noSubcategories) { - filter += "/none"; + if (this.noSubcategories !== undefined) { + filter += this.noSubcategories ? "/none" : "/all"; } filter += `/${tagId}/l/${topicFilter}`; @@ -120,12 +120,17 @@ export default DiscourseRoute.extend(FilterModeMixin, { }, setupController(controller, model) { + const noSubcategories = + this.noSubcategories === undefined + ? model.category?.default_list_filter === "none" + : this.noSubcategories; + this.controllerFor("tag.show").setProperties({ model: model.tag, ...model, period: model.list.for_period, navMode: this.navMode, - noSubcategories: this.noSubcategories, + noSubcategories, loading: false, }); this.searchService.set("searchContext", model.tag.searchContext); diff --git a/app/assets/javascripts/discourse/tests/acceptance/tags-test.js b/app/assets/javascripts/discourse/tests/acceptance/tags-test.js index 1b8ea803d4e..a5ea8d1959b 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/tags-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/tags-test.js @@ -288,25 +288,31 @@ acceptance("Tag info", function (needs) { }); }); - server.get("/tags/c/faq/4/planters/l/latest.json", () => { - return helper.response({ - users: [], - primary_groups: [], - topic_list: { - can_create_topic: true, - draft: null, - draft_key: "new_topic", - draft_sequence: 1, - per_page: 30, - tags: [ - { - id: 1, - name: "planters", - topic_count: 1, - }, - ], - topics: [], - }, + [ + "/tags/c/faq/4/planters/l/latest.json", + "/tags/c/feature/2/planters/l/latest.json", + "/tags/c/feature/2/none/planters/l/latest.json", + ].forEach((url) => { + server.get(url, () => { + return helper.response({ + users: [], + primary_groups: [], + topic_list: { + can_create_topic: true, + draft: null, + draft_key: "new_topic", + draft_sequence: 1, + per_page: 30, + tags: [ + { + id: 1, + name: "planters", + topic_count: 1, + }, + ], + topics: [], + }, + }); }); }); @@ -484,6 +490,20 @@ acceptance("Tag info", function (needs) { assert.strictEqual(currentURL(), "/tags/c/faq/4/planters"); }); + test("can switch between all/none subcategories", async function (assert) { + await visit("/tag/planters"); + + await click(".category-breadcrumb .category-drop-header"); + await click('.category-breadcrumb .category-row[data-name="feature"]'); + assert.strictEqual(currentURL(), "/tags/c/feature/2/planters"); + + await click(".category-breadcrumb li:nth-of-type(2) .category-drop-header"); + await click( + '.category-breadcrumb li:nth-of-type(2) .category-row[data-name="none"]' + ); + assert.strictEqual(currentURL(), "/tags/c/feature/2/none/planters"); + }); + test("admin can manage tags", async function (assert) { updateCurrentUser({ moderator: false, admin: true }); diff --git a/app/assets/javascripts/discourse/tests/fixtures/site-fixtures.js b/app/assets/javascripts/discourse/tests/fixtures/site-fixtures.js index af84a0c6452..a28ca8800f6 100644 --- a/app/assets/javascripts/discourse/tests/fixtures/site-fixtures.js +++ b/app/assets/javascripts/discourse/tests/fixtures/site-fixtures.js @@ -461,6 +461,7 @@ export default { show_subcategory_list: true, default_view: "latest", subcategory_list_style: "boxes", + default_list_filter: "all", }, { id: 240, diff --git a/config/routes.rb b/config/routes.rb index b658b7f1ca8..75066b99c9b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -952,9 +952,11 @@ Discourse::Application.routes.draw do scope path: '/c/*category_slug_path_with_id' do Discourse.filters.each do |filter| get "/none/:tag_id/l/#{filter}" => "tags#show_#{filter}", as: "tag_category_none_show_#{filter}", defaults: { no_subcategories: true } + get "/all/:tag_id/l/#{filter}" => "tags#show_#{filter}", as: "tag_category_all_show_#{filter}", defaults: { no_subcategories: false } end get '/none/:tag_id' => 'tags#show', as: 'tag_category_none_show', defaults: { no_subcategories: true } + get '/all/:tag_id' => 'tags#show', as: 'tag_category_all_show', defaults: { no_subcategories: false } Discourse.filters.each do |filter| get "/:tag_id/l/#{filter}" => "tags#show_#{filter}", as: "tag_category_show_#{filter}"